aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.bp5
-rw-r--r--java/aapt2.go23
-rw-r--r--java/aar.go67
-rw-r--r--java/aar_test.go28
-rw-r--r--java/android_manifest.go2
-rw-r--r--java/androidmk.go14
-rw-r--r--java/apkcerts.go126
-rw-r--r--java/app.go194
-rw-r--r--java/app_import.go65
-rw-r--r--java/app_set.go14
-rw-r--r--java/app_test.go192
-rw-r--r--java/base.go297
-rw-r--r--java/base_gob_enc.go89
-rw-r--r--java/boot_jars.go15
-rw-r--r--java/bootclasspath.go37
-rw-r--r--java/bootclasspath_fragment.go85
-rw-r--r--java/builder.go294
-rw-r--r--java/classpath_element.go26
-rw-r--r--java/classpath_fragment.go28
-rw-r--r--java/config/config.go3
-rw-r--r--java/config/kotlin.go2
-rw-r--r--java/device_host_converter.go21
-rw-r--r--java/dex.go358
-rw-r--r--java/dexpreopt.go2
-rw-r--r--java/dexpreopt_bootjars.go80
-rw-r--r--java/dexpreopt_check.go11
-rw-r--r--java/dexpreopt_test.go41
-rw-r--r--java/droiddoc.go13
-rw-r--r--java/droidstubs.go40
-rw-r--r--java/fuzz.go87
-rw-r--r--java/genrule_combiner.go14
-rw-r--r--java/hiddenapi.go15
-rw-r--r--java/hiddenapi_modular.go118
-rw-r--r--java/hiddenapi_monolithic.go7
-rw-r--r--java/jacoco.go64
-rw-r--r--java/java.go344
-rw-r--r--java/java_gob_enc.go54
-rw-r--r--java/java_test.go70
-rw-r--r--java/jdeps.go2
-rw-r--r--java/kotlin.go260
-rw-r--r--java/kotlin_test.go126
-rw-r--r--java/lint.go37
-rw-r--r--java/lint_gob_enc.go110
-rw-r--r--java/platform_bootclasspath.go22
-rw-r--r--java/platform_compat_config.go40
-rw-r--r--java/prebuilt_apis_test.go4
-rw-r--r--java/ravenwood.go109
-rw-r--r--java/ravenwood_test.go28
-rw-r--r--java/robolectric.go3
-rw-r--r--java/rro.go29
-rw-r--r--java/rro_test.go2
-rw-r--r--java/sdk.go2
-rw-r--r--java/sdk_library.go261
-rw-r--r--java/sdk_library_internal.go40
-rw-r--r--java/sdk_library_test.go4
-rw-r--r--java/system_modules.go34
-rw-r--r--java/system_modules_gob_enc.go137
-rw-r--r--java/systemserver_classpath_fragment.go33
-rw-r--r--java/testing.go14
59 files changed, 3411 insertions, 831 deletions
diff --git a/java/Android.bp b/java/Android.bp
index 99d9c38a6..65200c27a 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -27,11 +27,13 @@ bootstrap_go_package {
"android_manifest.go",
"android_resources.go",
"androidmk.go",
+ "apkcerts.go",
"app_builder.go",
"app.go",
"app_import.go",
"app_set.go",
"base.go",
+ "base_gob_enc.go",
"boot_jars.go",
"bootclasspath.go",
"bootclasspath_fragment.go",
@@ -58,10 +60,12 @@ bootstrap_go_package {
"hiddenapi_singleton.go",
"jacoco.go",
"java.go",
+ "java_gob_enc.go",
"jdeps.go",
"java_resources.go",
"kotlin.go",
"lint.go",
+ "lint_gob_enc.go",
"legacy_core_platform_api_usage.go",
"platform_bootclasspath.go",
"platform_compat_config.go",
@@ -76,6 +80,7 @@ bootstrap_go_package {
"sdk_library_internal.go",
"support_libraries.go",
"system_modules.go",
+ "system_modules_gob_enc.go",
"systemserver_classpath_fragment.go",
"testing.go",
"tracereferences.go",
diff --git a/java/aapt2.go b/java/aapt2.go
index bae4d1ee3..4efa6655a 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -52,14 +52,15 @@ func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.Writab
}
subDir := filepath.Dir(res.String())
subDir, lastDir := filepath.Split(subDir)
- if isFlagsPath(subDir) {
- var flag string
+ var flag string
+ if isFlagsPath(lastDir) {
+ flag = "." + strings.TrimPrefix(lastDir, "flag")
+ subDir, lastDir = filepath.Split(filepath.Dir(subDir))
+ } else if isFlagsPath(subDir) {
subDir, flag = filepath.Split(filepath.Dir(subDir))
- flag = strings.TrimPrefix(flag, "flag")
- name = fmt.Sprintf("%s_%s.%s%s.flat", lastDir, name, flag, extension)
- } else {
- name = fmt.Sprintf("%s_%s%s.flat", lastDir, name, extension)
+ flag = "." + strings.TrimPrefix(flag, "flag")
}
+ name = fmt.Sprintf("%s_%s%s%s.flat", lastDir, name, flag, extension)
out := android.PathForModuleOut(ctx, "aapt2", subDir, name)
return out
}
@@ -332,15 +333,20 @@ func aapt2ExtractExtraPackages(ctx android.ModuleContext, out android.WritablePa
var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
blueprint.RuleParams{
- Command: `${config.Aapt2Cmd} convert --enable-compact-entries ` +
+ Command: `${config.Aapt2Cmd} convert $flags ` +
`--output-format $format $in -o $out`,
CommandDeps: []string{"${config.Aapt2Cmd}"},
- }, "format",
+ }, "format", "flags",
)
// 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, format string) {
+ extraFlags := []string{"--enable-compact-entries"}
+ if ctx.Config().ReleaseUseSparseEncoding() {
+ extraFlags = append(extraFlags, "--enable-sparse-encoding")
+ }
+
ctx.Build(pctx, android.BuildParams{
Rule: aapt2ConvertRule,
Input: in,
@@ -348,6 +354,7 @@ func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in androi
Description: "convert to " + format,
Args: map[string]string{
"format": format,
+ "flags": strings.Join(extraFlags, " "),
},
})
}
diff --git a/java/aar.go b/java/aar.go
index ad080aa62..c1129f0c8 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -108,6 +108,9 @@ type aaptProperties struct {
// Names of aconfig_declarations modules that specify aconfig flags that the module depends on.
Flags_packages []string
+
+ // The package name of this app. May not be used if `manifest` or `additional_manifests` are provided.
+ Package_name proptools.Configurable[string]
}
type aapt struct {
@@ -144,6 +147,10 @@ type aapt struct {
manifestValues struct {
applicationId string
}
+
+ // Fields written to jdeps
+ assetDirs android.Paths
+ resourceDirs android.Paths
}
type split struct {
@@ -263,6 +270,13 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
linkFlags = append(linkFlags, "--enable-compact-entries")
+ if ctx.Config().ReleaseUseSparseEncoding() {
+ linkFlags = append(linkFlags, "--enable-sparse-encoding")
+ }
+
+ if ctx.Config().ReleaseUseUncompressedFonts() {
+ linkFlags = append(linkFlags, "--no-compress-fonts")
+ }
// Find implicit or explicit asset and resource dirs
assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{
@@ -276,7 +290,10 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte
} else {
assetDirs = android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
}
+ a.assetDirs = assetDirs
+
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs.GetOrDefault(ctx, nil), "res")
+ a.resourceDirs = resourceDirs
resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
// Glob directories into lists of paths
@@ -452,9 +469,21 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio
opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
// App manifest file
+ packageNameProp := a.aaptProperties.Package_name.Get(ctx)
var manifestFilePath android.Path
if opts.manifestForAapt != nil {
manifestFilePath = opts.manifestForAapt
+ } else if a.isLibrary && packageNameProp.IsPresent() && a.aaptProperties.Manifest == nil && a.aaptProperties.Additional_manifests == nil {
+ // If the only reason that a library needs a manifest file is to give the package name, allow them to do that in
+ // the module declaration. If they are already supplying a manifest, then do not autogenerate a manifest file.
+ generatedManifestPath := android.PathForModuleOut(ctx, "GeneratedManifest.xml")
+ manifestString := `<?xml version="1.0" encoding="utf-8"?>
+<!-- Automatically generated by Soong. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="` + packageNameProp.Get() + `" />
+`
+ android.WriteFileRule(ctx, generatedManifestPath, manifestString)
+ ctx.SetOutputFiles([]android.Path{generatedManifestPath}, ".gen_xml")
+ manifestFilePath = generatedManifestPath
} else {
manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
manifestFilePath = android.PathForModuleSrc(ctx, manifestFile)
@@ -975,6 +1004,17 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
}
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ packageNameProp := a.aaptProperties.Package_name.Get(ctx)
+ if packageNameProp.IsPresent() {
+ if a.aaptProperties.Manifest != nil {
+ ctx.PropertyErrorf("package_name", "cannot be used with `manifest`")
+ return
+ }
+ if a.aaptProperties.Additional_manifests != nil {
+ ctx.PropertyErrorf("package_name", "cannot be used with `additional_manifests`")
+ return
+ }
+ }
a.aapt.isLibrary = true
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
if a.usesLibrary.shouldDisableDexpreopt {
@@ -1042,6 +1082,7 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
var res android.Paths
if a.androidLibraryProperties.BuildAAR {
BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
+ android.SetProvider(ctx, AARProvider, AARInfo{Aar: a.aarFile})
}
prebuiltJniPackages := android.Paths{}
@@ -1070,6 +1111,11 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
a.setOutputFiles(ctx)
buildComplianceMetadata(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ moduleInfoJSON.ClassesJar = []string{a.Library.implementationAndResourcesJar.String()}
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) {
@@ -1086,6 +1132,8 @@ func (a *aapt) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
if a.rJar != nil {
dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
}
+ dpInfo.Asset_dirs = append(dpInfo.Asset_dirs, a.assetDirs.Strings()...)
+ dpInfo.Resource_dirs = append(dpInfo.Resource_dirs, a.resourceDirs.Strings()...)
}
// android_library builds and links sources into a `.jar` file for the device along with Android resources.
@@ -1248,10 +1296,6 @@ func (a *AARImport) Name() string {
return a.prebuilt.Name(a.ModuleBase.Name())
}
-func (a *AARImport) JacocoReportClassesFile() android.Path {
- return nil
-}
-
func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
if !ctx.Config().AlwaysUsePrebuiltSdks() {
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
@@ -1267,6 +1311,7 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs.GetOrDefault(ctx, nil)...)
a.usesLibrary.deps(ctx, false)
+ a.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
type JniPackageInfo struct {
@@ -1585,6 +1630,11 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
buildComplianceMetadata(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ moduleInfoJSON.ClassesJar = []string{a.implementationAndResourcesJarFile.String()}
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (a *AARImport) HeaderJars() android.Paths {
@@ -1656,5 +1706,12 @@ func AARImportFactory() android.Module {
}
func (a *AARImport) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
- dpInfo.Jars = append(dpInfo.Jars, a.implementationJarFile.String(), a.rJar.String())
+ dpInfo.Jars = append(dpInfo.Jars, a.implementationJarFile.String(), a.rJar.String(), a.aarPath.String())
+ dpInfo.Static_libs = append(dpInfo.Static_libs, a.properties.Static_libs.GetOrDefault(ctx, nil)...)
+}
+
+type AARInfo struct {
+ Aar android.Path
}
+
+var AARProvider = blueprint.NewProvider[AARInfo]()
diff --git a/java/aar_test.go b/java/aar_test.go
index 088ad6c92..520759682 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -131,7 +131,7 @@ func TestLibraryFlagsPackages(t *testing.T) {
android.AssertStringDoesContain(t,
"aapt2 link command expected to pass feature flags arguments",
linkInFlags,
- "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt",
)
}
@@ -181,3 +181,29 @@ func TestAndroidLibraryOutputFilesRel(t *testing.T) {
android.AssertStringEquals(t, "baz relative output path",
"baz.jar", bazOutputPaths[0].Rel())
}
+
+func TestAndroidLibraryManifests(t *testing.T) {
+ t.Parallel()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ android_library {
+ name: "foo",
+ package_name: "com.android.foo",
+ java_resources: ["foo.txt"],
+ }
+ `)
+
+ foo := result.ModuleForTests(t, "foo", "android_common")
+
+ fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
+
+ android.AssertPathsRelativeToTopEquals(t, "foo manifest path",
+ []string{"out/soong/.intermediates/foo/android_common/GeneratedManifest.xml"},
+ foo.OutputFiles(result.TestContext, t, ".gen_xml"))
+ android.AssertPathsRelativeToTopEquals(t, "foo output path",
+ []string{"out/soong/.intermediates/foo/android_common/withres/foo.jar"}, fooOutputPaths)
+
+ android.AssertStringEquals(t, "foo relative output path",
+ "foo.jar", fooOutputPaths[0].Rel())
+}
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 7dd95c9ac..a7453ee6b 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -68,7 +68,7 @@ func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLev
return false
}
// If this a module targeting an unreleased SDK (MTS or unbundled builds), return 10000
- return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module()))
+ return targetSdkVersionLevel.IsPreview() && (ctx.Config().HasUnbundledBuildApps() || includedInMts(ctx.Module()))
}
// Helper function that returns true if android_test, android_test_helper_app, java_test are in an MTS suite.
diff --git a/java/androidmk.go b/java/androidmk.go
index f155232de..97707d76b 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -102,8 +102,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", library.implementationAndResourcesJar)
entries.SetPath("LOCAL_SOONG_HEADER_JAR", library.headerJarFile)
- if library.jacocoReportClassesFile != nil {
- entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoReportClassesFile)
+ if library.jacocoInfo.ReportClassesFile != nil {
+ entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoInfo.ReportClassesFile)
}
requiredUsesLibs, optionalUsesLibs := library.classLoaderContexts.UsesLibs()
@@ -113,8 +113,6 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_USAGE_ZIP", library.dexer.proguardUsageZip)
entries.SetString("LOCAL_MODULE_STEM", library.Stem())
- entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
-
if library.dexpreopter.configPath != nil {
entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath)
}
@@ -336,8 +334,8 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
if app.bundleFile != nil {
entries.SetPath("LOCAL_SOONG_BUNDLE", app.bundleFile)
}
- if app.jacocoReportClassesFile != nil {
- entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", app.jacocoReportClassesFile)
+ if app.jacocoInfo.ReportClassesFile != nil {
+ entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", app.jacocoInfo.ReportClassesFile)
}
entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_DICT", app.dexer.proguardDictionary)
entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_USAGE_ZIP", app.dexer.proguardUsageZip)
@@ -359,7 +357,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", app.getOverriddenPackages()...)
if app.embeddedJniLibs {
- jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String())
+ jniSymbols := JNISymbolsInstalls(app.jniLibs, app.installPathForJNISymbols.String())
entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String())
} else {
var names []string
@@ -383,8 +381,6 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
}
- entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
-
entries.AddStrings("LOCAL_SOONG_LOGTAGS_FILES", app.logtagsSrcs.Strings()...)
},
},
diff --git a/java/apkcerts.go b/java/apkcerts.go
new file mode 100644
index 000000000..8aba27b9d
--- /dev/null
+++ b/java/apkcerts.go
@@ -0,0 +1,126 @@
+// Copyright 2015 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"
+ "fmt"
+ "slices"
+ "strings"
+
+ "github.com/google/blueprint"
+)
+
+func init() {
+ android.InitRegistrationContext.RegisterParallelSingletonType("apkcerts_singleton", apkCertsSingletonFactory)
+}
+
+// Info that should be included into the apkcerts.txt file.
+// The info can be provided as either a text file containing a subset of the final apkcerts.txt,
+// or as a certificate and name. The text file will be preferred if it exists
+type ApkCertInfo struct {
+ ApkCertsFile android.Path
+
+ Certificate Certificate
+ Name string
+
+ // True if LOCAL_MODULE_TAGS would contain "tests" in a make build.
+ // In make this caused the partition in the apkcerts.txt file to be "data" instead of "system"
+ Test bool
+}
+
+var ApkCertInfoProvider = blueprint.NewProvider[ApkCertInfo]()
+
+type ApkCertsInfo []ApkCertInfo
+
+var ApkCertsInfoProvider = blueprint.NewProvider[ApkCertsInfo]()
+
+func apkCertsSingletonFactory() android.Singleton {
+ return &apkCertsSingleton{}
+}
+
+type apkCertsSingleton struct{}
+
+func (a *apkCertsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ apkCerts := []string{}
+ var apkCertsFiles android.Paths
+ ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+ commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
+ if !ok || commonInfo.SkipAndroidMkProcessing {
+ return
+ }
+ if info, ok := android.OtherModuleProvider(ctx, m, android.HideApexVariantFromMakeProvider); ok && info.HideApexVariantFromMake {
+ return
+ }
+
+ partition := commonInfo.PartitionTag
+
+ specifiesPartition := commonInfo.SocSpecific || commonInfo.Vendor ||
+ commonInfo.Proprietary || commonInfo.SystemExtSpecific || commonInfo.ProductSpecific ||
+ commonInfo.DeviceSpecific
+
+ if info, ok := android.OtherModuleProvider(ctx, m, ApkCertsInfoProvider); ok {
+ for _, certInfo := range info {
+ if certInfo.ApkCertsFile != nil {
+ apkCertsFiles = append(apkCertsFiles, certInfo.ApkCertsFile)
+ } else {
+ // Partition information of apk-in-apex is not exported to the legacy Make packaging system.
+ // Hardcode the partition to "system"
+ apkCerts = append(apkCerts, FormatApkCertsLine(certInfo.Certificate, certInfo.Name, "system"))
+ }
+ }
+ } else if info, ok := android.OtherModuleProvider(ctx, m, ApkCertInfoProvider); ok {
+ if info.ApkCertsFile != nil {
+ apkCertsFiles = append(apkCertsFiles, info.ApkCertsFile)
+ } else {
+ // From base_rules.mk
+ if info.Test && partition == "system" && !specifiesPartition {
+ partition = "data"
+ }
+
+ apkCerts = append(apkCerts, FormatApkCertsLine(info.Certificate, info.Name, partition))
+ }
+ }
+ })
+ slices.Sort(apkCerts) // sort by name
+ apkCertsInfoWithoutAppSets := android.PathForOutput(ctx, "apkcerts_singleton", "apkcerts_without_app_sets.txt")
+ android.WriteFileRule(ctx, apkCertsInfoWithoutAppSets, strings.Join(apkCerts, "\n"))
+ apkCertsInfo := ApkCertsFile(ctx)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CatAndSortAndUnique,
+ Description: "combine apkcerts.txt",
+ Output: apkCertsInfo,
+ Inputs: append(apkCertsFiles, apkCertsInfoWithoutAppSets),
+ })
+}
+
+func (s *apkCertsSingleton) MakeVars(ctx android.MakeVarsContext) {
+ ctx.Strict("SOONG_APKCERTS_FILE", ApkCertsFile(ctx).String())
+}
+
+func ApkCertsFile(ctx android.PathContext) android.WritablePath {
+ return android.PathForOutput(ctx, "apkcerts_singleton", "apkcerts.txt")
+}
+
+func FormatApkCertsLine(cert Certificate, name, partition string) string {
+ pem := cert.AndroidMkString()
+ var key string
+ if cert.Key == nil {
+ key = ""
+ } else {
+ key = cert.Key.String()
+ }
+ return fmt.Sprintf(`name="%s" certificate="%s" private_key="%s" partition="%s"`, name, pem, key, partition)
+}
diff --git a/java/app.go b/java/app.go
index 8ed0b46f4..cb1f36fa5 100644
--- a/java/app.go
+++ b/java/app.go
@@ -78,15 +78,20 @@ type AppInfo struct {
Privileged bool
OutputFile android.Path
InstallApkName string
- JacocoReportClassesFile android.Path
+ JacocoInfo JacocoInfo
Certificate Certificate
PrivAppAllowlist android.OptionalPath
OverriddenManifestPackageName *string
ApkCertsFile android.Path
+ JniLibs []jniLib
+ JniCoverageOutputs android.Paths
+ PackedAdditionalOutputs android.Path
}
var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
+type AppInfos []AppInfo
+
// AndroidManifest.xml merging
// package splits
@@ -413,11 +418,18 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon
TestOnly: true,
})
appInfo := &AppInfo{
- Updatable: Bool(a.appProperties.Updatable),
- TestHelperApp: true,
+ Updatable: Bool(a.appProperties.Updatable),
+ TestHelperApp: true,
+ JniLibs: a.jniLibs,
+ JniCoverageOutputs: a.jniCoverageOutputs,
}
setCommonAppInfo(appInfo, a)
android.SetProvider(ctx, AppInfoProvider, appInfo)
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: appInfo.Certificate,
+ Name: appInfo.InstallApkName + ".apk",
+ Test: true,
+ })
moduleInfoJSON := ctx.ModuleInfoJSON()
moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests")
@@ -427,11 +439,43 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon
moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
}
- android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
- TestSuites: a.appTestHelperAppProperties.Test_suites,
+ var data []android.DataPath
+ for _, d := range a.extraOutputFiles {
+ data = append(data, android.DataPath{SrcPath: d})
+ }
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: a.appTestHelperAppProperties.Test_suites,
+ MainFile: a.outputFile,
+ MainFileStem: a.installApkName,
+ MainFileExt: ".apk",
+ NeedsArchFolder: true,
+ NonArchData: data,
+ PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory),
+ DisableTestConfig: true,
})
}
+func (a *AndroidApp) baseSymbolInfo(ctx android.ModuleContext) *cc.SymbolInfo {
+ return &cc.SymbolInfo{
+ Name: a.BaseModuleName(),
+ ModuleDir: ctx.ModuleDir(),
+ Uninstallable: a.IsSkipInstall() || !proptools.BoolDefault(a.properties.Installable, true) || a.NoFullInstall(),
+ }
+}
+
+func (a *AndroidApp) GetJniSymbolInfos(ctx android.ModuleContext, JniSymbolInstallPath android.Path) []*cc.SymbolInfo {
+ infos := []*cc.SymbolInfo{}
+ for _, install := range JNISymbolsInstalls(a.jniLibs, JniSymbolInstallPath.String()) {
+ info := a.baseSymbolInfo(ctx)
+ info.UnstrippedBinaryPath = install.From
+ info.ModuleDir = filepath.Dir(install.To)
+ info.InstalledStem = filepath.Base(install.To)
+
+ infos = append(infos, info)
+ }
+ return infos
+}
+
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.checkAppSdkVersions(ctx)
a.checkEmbedJnis(ctx)
@@ -452,15 +496,21 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
EmbeddedJNILibs: embeddedJniLibs,
MergedManifestFile: a.mergedManifest,
OverriddenManifestPackageName: &overriddenName,
+ JniLibs: a.jniLibs,
+ JniCoverageOutputs: a.jniCoverageOutputs,
}
setCommonAppInfo(appInfo, a)
android.SetProvider(ctx, AppInfoProvider, appInfo)
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: appInfo.Certificate,
+ Name: appInfo.InstallApkName + ".apk",
+ })
a.requiredModuleNames = a.getRequiredModuleNames(ctx)
if a.dexer.proguardDictionary.Valid() {
android.SetProvider(ctx, ProguardProvider, ProguardInfo{
- ModuleName: ctx.ModuleName(),
+ ModuleName: android.ModuleNameWithPossibleOverride(ctx),
Class: "APPS",
ProguardDictionary: a.dexer.proguardDictionary.Path(),
ProguardUsageZip: a.dexer.proguardUsageZip.Path(),
@@ -836,9 +886,9 @@ func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages andro
return jniJarFile
}
-func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls {
+func JNISymbolsInstalls(jniLibs []jniLib, installPath string) android.RuleBuilderInstalls {
var jniSymbols android.RuleBuilderInstalls
- for _, jniLib := range a.jniLibs {
+ for _, jniLib := range jniLibs {
if jniLib.unstrippedFile != nil {
jniSymbols = append(jniSymbols, android.RuleBuilderInstall{
From: jniLib.unstrippedFile,
@@ -937,12 +987,17 @@ func (a *AndroidApp) createPrivappAllowlist(ctx android.ModuleContext) android.P
}
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+ a.jacocoInfo.Class = "APPS"
+
var apkDeps android.Paths
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
if !apexInfo.IsForPlatform() {
a.hideApexVariantFromMake = true
}
+ android.SetProvider(ctx, android.HideApexVariantFromMakeProvider, android.HideApexVariantFromMakeInfo{
+ HideApexVariantFromMake: a.hideApexVariantFromMake,
+ })
a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
@@ -1011,7 +1066,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
a.linter.mergedManifest = a.aapt.mergedManifestFile
a.linter.manifest = a.aapt.manifestPath
a.linter.resources = a.aapt.resourceFiles
- a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
+ a.linter.buildModuleReportZip = ctx.Config().HasUnbundledBuildApps()
dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
@@ -1079,6 +1134,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
bundleFile := android.PathForModuleOut(ctx, "base.zip")
BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
a.bundleFile = bundleFile
+ android.SetProvider(ctx, BundleProvider, BundleInfo{Bundle: bundleFile})
allowlist := a.createPrivappAllowlist(ctx)
if allowlist != nil {
@@ -1115,7 +1171,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
}
}
}
- ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
+ a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
}
ctx.CheckbuildFile(a.outputFile)
@@ -1151,6 +1207,14 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
a.setOutputFiles(ctx)
buildComplianceMetadata(ctx)
+
+ if !a.hideApexVariantFromMake && !a.IsHideFromMake() {
+ if a.embeddedJniLibs {
+ cc.CopySymbolsAndSetSymbolsInfoProvider(ctx, &cc.SymbolInfos{
+ Symbols: a.GetJniSymbolInfos(ctx, a.installPathForJNISymbols),
+ })
+ }
+ }
}
func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
@@ -1323,7 +1387,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
// Skip dependencies that are only available to APEXes; they are developed with updatability
// in mind and don't need manual approval.
- if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
+ if android.OtherModuleProviderOrDefault(ctx, to, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform {
return true
}
@@ -1458,7 +1522,7 @@ func AndroidAppFactory() android.Module {
return
}
- rroPackageName := a.Name() + "__" + strings.ReplaceAll(characteristics, ",", "_") + "__auto_generated_characteristics_rro"
+ rroPackageName := AutogeneratedProductCharacteristicsRroModuleName(ctx, a.Name())
rroManifestName := rroPackageName + "_manifest"
a.appProperties.ProductCharacteristicsRROPackageName = proptools.StringPtr(rroPackageName)
@@ -1511,7 +1575,19 @@ func AndroidAppFactory() android.Module {
}
func AutogeneratedRroModuleName(ctx android.EarlyModuleContext, moduleName, partition string) string {
- return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().DeviceProduct(), partition)
+ // auto_generated_rro is installed to the product or vendor partition and
+ // are specific to target product. To add the auto_generated_rro to the
+ // required list of the original app module, the target product name is
+ // required.
+ // TODO(b/412526509): Remove the rro dependency from the system partition.
+ // So, the original system module does not need to know the target product
+ // name. Instead, add a reverse dependency from the rro to the original
+ // system module to see if the module exists.
+ return fmt.Sprintf("%s__%s__auto_generated_rro_%s", moduleName, ctx.Config().Getenv("TARGET_PRODUCT"), partition)
+}
+
+func AutogeneratedProductCharacteristicsRroModuleName(ctx android.EarlyModuleContext, moduleName string) string {
+ return moduleName + "__" + strings.ReplaceAll(ctx.Config().ProductAAPTCharacteristics(), ",", "_") + "__auto_generated_characteristics_rro"
}
type createModuleContext interface {
@@ -1646,6 +1722,12 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
a.generateAndroidBuildActions(ctx)
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: a.Certificate(),
+ Name: a.InstallApkName() + ".apk",
+ Test: true,
+ })
+
for _, c := range a.testProperties.Test_options.Tradefed_options {
configs = append(configs, c)
}
@@ -1664,22 +1746,29 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...)
a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...)
- // Install test deps
- if !ctx.Config().KatiEnabled() {
- pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name())
- if a.testConfig != nil {
- ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig)
- }
- dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
- if dynamicConfig.Valid() {
- ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path())
- }
- testDeps := append(a.data, a.extraTestConfigs...)
- for _, data := range android.SortedUniquePaths(testDeps) {
- dataPath := android.DataPath{SrcPath: data}
- ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
- }
- }
+ a.data = android.SortedUniquePaths(a.data)
+ a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs)
+
+ var testData []android.DataPath
+ for _, data := range a.data {
+ dataPath := android.DataPath{SrcPath: data}
+ testData = append(testData, dataPath)
+ }
+ for _, d := range a.extraOutputFiles {
+ testData = append(testData, android.DataPath{SrcPath: d})
+ }
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ MainFile: a.outputFile,
+ MainFileStem: a.installApkName,
+ MainFileExt: ".apk",
+ ConfigFile: a.testConfig,
+ ExtraConfigs: a.extraTestConfigs,
+ NonArchData: testData,
+ CompatibilitySupportFiles: a.data,
+ NeedsArchFolder: true,
+ PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory),
+ })
android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
TestcaseRelDataFiles: testcaseRel(a.data),
@@ -1714,10 +1803,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
moduleInfoJSON.AutoTestConfig = []string{"true"}
}
moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
-
- android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
- TestSuites: a.testProperties.Test_suites,
- })
}
func testcaseRel(paths android.Paths) []string {
@@ -2047,14 +2132,31 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo
}
}
+func (u *usesLibrary) depsFromLibs(ctx android.BottomUpMutatorContext, libDeps []android.Module) {
+ // For library dependencies that are component libraries (like stubs), add the implementation
+ // as a dependency (dexpreopt needs to be against the implementation library, not stubs).
+ for _, dep := range libDeps {
+ if dep != nil {
+ if component, ok := android.OtherModuleProvider(ctx, dep, SdkLibraryComponentDependencyInfoProvider); ok {
+ if lib := component.OptionalSdkLibraryImplementation; lib != nil {
+ // Add library as optional if it's one of the optional compatibility libs or it's
+ // explicitly listed in the optional_uses_libs property.
+ tag := usesLibReqTag
+ if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
+ android.InList(*lib, u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
+ tag = usesLibOptTag
+ }
+ ctx.AddVariationDependencies(nil, tag, *lib)
+ }
+ }
+ }
+ }
+}
+
// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
- exists := ctx.OtherModuleExists(s)
- if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
- fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
- }
- return exists
+ return ctx.OtherModuleExists(s)
})
return optionalUsesLibs
}
@@ -2085,7 +2187,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext
// Skip stub libraries. A dependency on the implementation library has been added earlier,
// so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
// from implementation libraries by their name, which is different as it has a suffix.
- if comp := javaInfo.SdkLibraryComponentDependencyInfo; comp != nil {
+ if comp, ok := android.OtherModuleProvider(ctx, m, SdkLibraryComponentDependencyInfoProvider); ok {
if impl := comp.OptionalSdkLibraryImplementation; impl != nil && *impl != dep {
return
}
@@ -2180,6 +2282,10 @@ func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile a
cmd.FlagWithArg("--missing-optional-uses-library ", lib)
}
+ for _, lib := range ctx.Config().BootJars() {
+ cmd.FlagWithArg("--bootclasspath-libs ", lib)
+ }
+
rule.Build("verify_uses_libraries", "verify <uses-library>")
return outputFile
}
@@ -2206,7 +2312,7 @@ type androidApp interface {
Privileged() bool
InstallApkName() string
OutputFile() android.Path
- JacocoReportClassesFile() android.Path
+ JacocoInfo() JacocoInfo
Certificate() Certificate
BaseModuleName() string
PrivAppAllowlist() android.OptionalPath
@@ -2220,11 +2326,13 @@ func setCommonAppInfo(appInfo *AppInfo, m androidApp) {
appInfo.Privileged = m.Privileged()
appInfo.OutputFile = m.OutputFile()
appInfo.InstallApkName = m.InstallApkName()
- appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile()
+ appInfo.JacocoInfo = m.JacocoInfo()
appInfo.Certificate = m.Certificate()
appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
}
-type AppInfos []AppInfo
+type BundleInfo struct {
+ Bundle android.Path
+}
-var AppInfosProvider = blueprint.NewProvider[AppInfos]()
+var BundleProvider = blueprint.NewProvider[BundleInfo]()
diff --git a/java/app_import.go b/java/app_import.go
index 9fb13ba3c..93686a991 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -105,8 +105,6 @@ type AndroidAppImport struct {
installPath android.InstallPath
hideApexVariantFromMake bool
-
- provenanceMetaDataFile android.Path
}
type AndroidAppImportProperties struct {
@@ -122,7 +120,7 @@ type AndroidAppImportProperties struct {
// Set this flag to true if the prebuilt apk is already signed. The certificate property must not
// be set for presigned modules.
- Presigned *bool
+ Presigned proptools.Configurable[bool] `android:"replace_instead_of_append"`
// Name of the signing certificate lineage file or filegroup module.
Lineage *string `android:"path"`
@@ -157,7 +155,7 @@ type AndroidAppImportProperties struct {
Relative_install_path *string
// Whether the prebuilt apk can be installed without additional processing. Default is false.
- Preprocessed *bool
+ Preprocessed proptools.Configurable[bool] `android:"replace_instead_of_append"`
// Whether or not to skip checking the preprocessed apk for proper alignment and uncompressed
// JNI libs and dex files. Default is false
@@ -289,7 +287,7 @@ func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
// with them may invalidate pre-existing signature data.
- if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || Bool(a.properties.Preprocessed)) {
+ if ctx.InstallInTestcases() && (a.properties.Presigned.GetOrDefault(ctx, false) || a.properties.Preprocessed.GetOrDefault(ctx, false)) {
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Output: outputPath,
@@ -320,7 +318,7 @@ func (a *AndroidAppImport) extractSubApk(
// Returns whether this module should have the dex file stored uncompressed in the APK.
func (a *AndroidAppImport) shouldUncompressDex(ctx android.ModuleContext) bool {
- if ctx.Config().UnbundledBuild() || proptools.Bool(a.properties.Preprocessed) {
+ if ctx.Config().UnbundledBuild() || a.properties.Preprocessed.GetOrDefault(ctx, false) {
return false
}
@@ -355,11 +353,19 @@ func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch(
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"APPS"}
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+
appInfo := &AppInfo{
Prebuilt: true,
}
setCommonAppInfo(appInfo, a)
android.SetProvider(ctx, AppInfoProvider, appInfo)
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: appInfo.Certificate,
+ Name: appInfo.InstallApkName + ".apk",
+ })
}
func (a *AndroidAppImport) InstallApkName() string {
@@ -380,19 +386,18 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
a.hideApexVariantFromMake = true
}
- if Bool(a.properties.Preprocessed) {
- if a.properties.Presigned != nil && !*a.properties.Presigned {
+ if a.properties.Preprocessed.GetOrDefault(ctx, false) {
+ if !a.properties.Presigned.GetOrDefault(ctx, true) {
ctx.ModuleErrorf("Setting preprocessed: true implies presigned: true, so you cannot set presigned to false")
}
- t := true
- a.properties.Presigned = &t
+ a.properties.Presigned.AppendSimpleValue(true)
}
numCertPropsSet := 0
if a.properties.Certificate.GetOrDefault(ctx, "") != "" {
numCertPropsSet++
}
- if Bool(a.properties.Presigned) {
+ if a.properties.Presigned.GetOrDefault(ctx, false) {
numCertPropsSet++
}
if Bool(a.properties.Default_dev_cert) {
@@ -438,7 +443,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
installDir := android.PathForModuleInstall(ctx, pathFragments...)
a.dexpreopter.isApp = true
a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
- a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
+ a.dexpreopter.isPresignedPrebuilt = a.properties.Presigned.GetOrDefault(ctx, false)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
@@ -476,7 +481,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
// Sign or align the package if package has not been preprocessed
- if proptools.Bool(a.properties.Preprocessed) {
+ if a.properties.Preprocessed.GetOrDefault(ctx, false) {
validationStamp := a.validatePresignedApk(ctx, srcApk)
output := android.PathForModuleOut(ctx, apkFilename)
ctx.Build(pctx, android.BuildParams{
@@ -487,7 +492,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
})
a.outputFile = output
a.certificate = PresignedCertificate
- } else if !Bool(a.properties.Presigned) {
+ } else if !a.properties.Presigned.GetOrDefault(ctx, false) {
// 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 := collectAppDeps(ctx, a, false, false)
@@ -524,7 +529,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
if apexInfo.IsForPlatform() {
a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
artifactPath := android.PathForModuleSrc(ctx, a.properties.Apk.GetOrDefault(ctx, ""))
- a.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath)
+ provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath)
}
providePrebuiltInfo(ctx,
@@ -554,7 +559,7 @@ func (a *AndroidAppImport) validatePresignedApk(ctx android.ModuleContext, srcAp
if proptools.Bool(a.properties.Skip_preprocessed_apk_checks) {
extraArgs = append(extraArgs, "--skip-preprocessed-apk-checks")
}
- if proptools.Bool(a.properties.Preprocessed) {
+ if a.properties.Preprocessed.GetOrDefault(ctx, false) {
extraArgs = append(extraArgs, "--preprocessed")
}
@@ -581,18 +586,14 @@ func (a *AndroidAppImport) OutputFile() android.Path {
return a.outputFile
}
-func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
- return nil
+func (a *AndroidAppImport) JacocoInfo() JacocoInfo {
+ return JacocoInfo{}
}
func (a *AndroidAppImport) Certificate() Certificate {
return a.certificate
}
-func (a *AndroidAppImport) ProvenanceMetaDataFile() android.Path {
- return a.provenanceMetaDataFile
-}
-
func (a *AndroidAppImport) PrivAppAllowlist() android.OptionalPath {
return android.OptionalPath{}
}
@@ -788,8 +789,24 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
- android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
- TestSuites: a.testProperties.Test_suites,
+ var data []android.DataPath
+ for _, d := range a.data {
+ data = append(data, android.DataPath{SrcPath: d})
+ }
+
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: a.testProperties.Test_suites,
+ MainFile: a.outputFile,
+ MainFileStem: a.outputFile.Base(),
+ NeedsArchFolder: true,
+ Data: data,
+ CompatibilitySupportFiles: a.data,
+ })
+
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: a.Certificate(),
+ Name: a.InstallApkName() + ".apk",
+ Test: true,
})
}
diff --git a/java/app_set.go b/java/app_set.go
index 6a2c678a8..e7bef6e4f 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -131,7 +131,7 @@ type prebuiltInfoProps struct {
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
// with information about whether source or prebuilt of an apex was used during the build.
func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
- info := android.PrebuiltInfo{
+ info := android.PrebuiltJsonInfo{
Name: p.baseModuleName,
Is_prebuilt: p.isPrebuilt,
}
@@ -140,7 +140,7 @@ func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo)
info.Prebuilt_info_file_path = prebuiltInfoFile.String()
}
- android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+ android.SetProvider(ctx, android.PrebuiltJsonInfoProvider, info)
}
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -193,9 +193,13 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
)
android.SetProvider(ctx, AppInfoProvider, &AppInfo{
- AppSet: true,
- Privileged: as.Privileged(),
- OutputFile: as.OutputFile(),
+ AppSet: true,
+ Privileged: as.Privileged(),
+ OutputFile: as.OutputFile(),
+ ApkCertsFile: as.apkcertsFile,
+ PackedAdditionalOutputs: as.packedOutput,
+ })
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
ApkCertsFile: as.apkcertsFile,
})
}
diff --git a/java/app_test.go b/java/app_test.go
index a8b39b7d1..a33c6b10c 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -15,6 +15,8 @@
package java
import (
+ "encoding/json"
+ "errors"
"fmt"
"path/filepath"
"reflect"
@@ -3475,9 +3477,6 @@ func TestUsesLibraries(t *testing.T) {
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"}
- }),
).RunTestWithBp(t, bp)
app := result.ModuleForTests(t, "app", "android_common")
@@ -3532,6 +3531,178 @@ func TestUsesLibraries(t *testing.T) {
"--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt")
}
+func extractContextJson(cmd string) (map[string]interface{}, error) {
+ var clc map[string]interface{}
+ for _, flag := range strings.Split(cmd, " ") {
+ if value, match := strings.CutPrefix(flag, "--context-json='"); match {
+ value = strings.TrimSuffix(value, "'")
+ if err := json.Unmarshal([]byte(value), &clc); err != nil {
+ return nil, err
+ }
+ return clc, nil
+ }
+ }
+ return nil, errors.New("--context-json not found")
+}
+
+func TestClassLoaderContext_SdkLibrary(t *testing.T) {
+ bp := `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ sdk_version: "current",
+ uses_libs: ["bar"],
+ }
+
+ java_sdk_library {
+ name: "bar",
+ srcs: ["b.java"],
+ api_packages: ["bar"],
+ sdk_version: "current",
+ }
+
+ android_app {
+ name: "app",
+ srcs: ["app.java"],
+ libs: ["foo.stubs"],
+ uses_libs: ["foo"],
+ sdk_version: "current",
+ }
+
+ android_app {
+ name: "app2",
+ srcs: ["app.java"],
+ libs: ["foo.impl"],
+ uses_libs: ["foo"],
+ sdk_version: "current",
+ }
+ `
+
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo", "bar"),
+ ).RunTestWithBp(t, bp)
+
+ {
+ fooXml := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
+ fooXmlContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooXml)
+ android.AssertStringDoesContain(t, "", fooXmlContents, `dependency="bar"`)
+ }
+
+ {
+ fooImpl := result.ModuleForTests(t, "foo.impl", "android_common")
+ cmd := fooImpl.Rule("dexpreopt").RuleParams.Command
+
+ clc, err := extractContextJson(cmd)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ deps := clc["any"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(deps))
+ bar := deps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "bar", bar["Name"].(string))
+ }
+
+ for _, name := range []string{"app", "app2"} {
+ app := result.ModuleForTests(t, name, "android_common")
+ cmd := app.Rule("dexpreopt").RuleParams.Command
+
+ clc, err := extractContextJson(cmd)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ deps := clc["any"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(deps))
+ foo := deps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "foo", foo["Name"].(string))
+ fooDeps := foo["Subcontexts"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(fooDeps))
+ bar := fooDeps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "bar", bar["Name"].(string))
+ }
+}
+
+func TestClassLoaderContext_SdkLibrary2(t *testing.T) {
+ bp := `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ sdk_version: "current",
+ libs: ["bar.impl"],
+ }
+
+ java_sdk_library {
+ name: "bar",
+ srcs: ["b.java"],
+ api_packages: ["bar"],
+ sdk_version: "current",
+ }
+
+ android_app {
+ name: "app",
+ srcs: ["app.java"],
+ libs: ["foo.stubs"],
+ uses_libs: ["foo"],
+ sdk_version: "current",
+ }
+ `
+
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo", "bar"),
+ ).RunTestWithBp(t, bp)
+
+ {
+ fooXml := result.ModuleForTests(t, "foo.xml", "android_common").Output("foo.xml")
+ fooXmlContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooXml)
+ android.AssertStringDoesContain(t, "", fooXmlContents, `dependency="bar"`)
+ }
+
+ {
+ fooImpl := result.ModuleForTests(t, "foo.impl", "android_common")
+ cmd := fooImpl.Rule("dexpreopt").RuleParams.Command
+
+ clc, err := extractContextJson(cmd)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ deps := clc["any"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(deps))
+ bar := deps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "bar", bar["Name"].(string))
+ }
+
+ {
+ app := result.ModuleForTests(t, "app", "android_common")
+ cmd := app.Rule("dexpreopt").RuleParams.Command
+
+ clc, err := extractContextJson(cmd)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ deps := clc["any"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(deps))
+ foo := deps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "foo", foo["Name"].(string))
+ fooDeps := foo["Subcontexts"].([]interface{})
+ android.AssertIntEquals(t, "", 1, len(fooDeps))
+ bar := fooDeps[0].(map[string]interface{})
+ android.AssertStringEquals(t, "", "bar", bar["Name"].(string))
+ }
+}
+
func TestDexpreoptBcp(t *testing.T) {
t.Parallel()
bp := `
@@ -4578,7 +4749,7 @@ func TestAppFlagsPackages(t *testing.T) {
android.AssertStringDoesContain(t,
"aapt2 link command expected to pass feature flags arguments",
linkInFlags,
- "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt",
)
aapt2CompileRule := foo.Rule("android/soong/java.aapt2Compile")
@@ -4586,7 +4757,7 @@ func TestAppFlagsPackages(t *testing.T) {
android.AssertStringDoesContain(t,
"aapt2 compile command expected to pass feature flags arguments",
compileFlags,
- "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt",
)
}
@@ -4658,12 +4829,12 @@ func TestAppFlagsPackagesPropagation(t *testing.T) {
android.AssertStringDoesContain(t,
"aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs",
linkInFlags,
- "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt",
)
android.AssertStringDoesNotContain(t,
"aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs",
linkInFlags,
- "--feature-flags @out/soong/.intermediates/foo/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/foo/aconfig-flags.txt",
)
}
@@ -4902,6 +5073,7 @@ func TestResourcesWithFlagDirectories(t *testing.T) {
"res/flag(!test.package.flag2)/values/bools.xml": nil,
"res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil,
"res/flags(test.package.flag1)/values/strings.xml": nil,
+ "res/drawable/flag(test.package.flag1)/qs_flashlight_icon_off.xml": nil,
}),
).RunTestWithBp(t, `
android_library {
@@ -4940,6 +5112,12 @@ func TestResourcesWithFlagDirectories(t *testing.T) {
compileOutputPaths,
"out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
)
+ android.AssertStringListContains(
+ t,
+ "Expected to generate flag path when it is a subdirectory of resource type subdirectory",
+ compileOutputPaths,
+ "out/soong/.intermediates/foo/android_common/aapt2/res/drawable_qs_flashlight_icon_off.(test.package.flag1).xml.flat",
+ )
}
func TestAutogeneratedStaticRro(t *testing.T) {
diff --git a/java/base.go b/java/base.go
index 8aa0109d0..7d56522b9 100644
--- a/java/base.go
+++ b/java/base.go
@@ -15,7 +15,6 @@
package java
import (
- "encoding/gob"
"fmt"
"path/filepath"
"reflect"
@@ -33,6 +32,8 @@ import (
"android/soong/java/config"
)
+//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go
+
// This file contains the definition and the implementation of the base module that most
// source-based Java module structs embed.
@@ -94,12 +95,18 @@ type CommonProperties struct {
// See kotlinc's `-language-version` flag.
Kotlin_lang_version *string
+ // Whether this target supports compilation with the kotlin-incremental-client.
+ Kotlin_incremental *bool
+
// list of java libraries that will be in the classpath
Libs []string `android:"arch_variant"`
// list of java libraries that will be compiled into the resulting jar
Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
+ // List of Kotlin libraries whose `internal` members are accessible to this library
+ Associates []string `android:"arch_variant"`
+
// manifest file to be included in resulting jar
Manifest *string `android:"path"`
@@ -229,6 +236,11 @@ type CommonProperties struct {
// If true, then only the headers are built and not the implementation jar.
Headers_only *bool
+ // If specified, this is used for this library's header jar, rather than generating it. This
+ // should only be used if the library adds nothing new to the header jars vs the provided path.
+ // For example, this could be used if the module only adds implementation code.
+ Header_jar_override string `android:"path,arch_variant"`
+
// A list of files or dependencies to make available to the build sandbox. This is
// useful if source files are symlinks, the targets of the symlinks must be listed here.
// Note that currently not all actions implemented by android_apps are sandboxed, so you
@@ -251,6 +263,9 @@ type CommonProperties struct {
// If true, the "Ravenizer" tool will remove all Mockito and DexMaker
// classes from the output jar.
Strip_mockito *bool
+
+ // Extra arguments passed to Ravenizer
+ Flags []string
}
// Contributing api surface of the stub module. Is not visible to bp modules, and should
@@ -505,11 +520,12 @@ type Module struct {
dexJarFile OptionalDexJarPath
// output file containing uninstrumented classes that will be instrumented by jacoco
- jacocoReportClassesFile android.Path
+ jacocoInfo JacocoInfo
// output file of the module, which may be a classes jar or a dex jar
- outputFile android.Path
- extraOutputFiles android.Paths
+ outputFile android.Path
+ installedOutputFile android.Path
+ extraOutputFiles android.Paths
exportAidlIncludeDirs android.Paths
ignoredAidlPermissionList android.Paths
@@ -867,6 +883,17 @@ func (j *Module) staticLibs(ctx android.BaseModuleContext) []string {
return j.properties.Static_libs.GetOrDefault(ctx, nil)
}
+func (j *Module) incrementalKotlin(config android.Config) bool {
+ incremental := proptools.BoolDefault(
+ j.properties.Kotlin_incremental, config.PartialCompileFlags().Enable_inc_kotlin)
+ nonIncrementalFlags := []string{"-Xmulti-platform", "-Xexpect-actual-classes"}
+ for _, flag := range nonIncrementalFlags {
+ incremental = incremental && !slices.Contains(j.properties.Kotlincflags, flag)
+ }
+
+ return incremental
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
j.linter.deps(ctx)
@@ -892,24 +919,7 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{})
ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...)
- // For library dependencies that are component libraries (like stubs), add the implementation
- // as a dependency (dexpreopt needs to be against the implementation library, not stubs).
- for _, dep := range libDeps {
- if dep != nil {
- if component, ok := dep.(SdkLibraryComponentDependency); ok {
- if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
- // Add library as optional if it's one of the optional compatibility libs or it's
- // explicitly listed in the optional_uses_libs property.
- tag := usesLibReqTag
- if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
- android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
- tag = usesLibOptTag
- }
- ctx.AddVariationDependencies(nil, tag, *lib)
- }
- }
- }
- }
+ j.usesLibrary.depsFromLibs(ctx, libDeps)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, j.properties.Kotlin_plugins...)
@@ -943,10 +953,17 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
+ incremental := j.incrementalKotlin(ctx.Config())
if j.useCompose(ctx) {
- ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
+ if incremental {
+ ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), composeEmbeddablePluginTag,
+ "kotlin-compose-compiler-embeddable-plugin")
+ }
+ ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), composePluginTag,
"kotlin-compose-compiler-plugin")
}
+
+ j.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
func hasSrcExt(srcs []string, ext string) bool {
@@ -1152,14 +1169,6 @@ func (j *Module) collectJavacFlags(
return flags
}
-func (j *Module) AddJSONData(d *map[string]interface{}) {
- (&j.ModuleBase).AddJSONData(d)
- (*d)["Java"] = map[string]interface{}{
- "SourceExtensions": j.sourceExtensions,
- }
-
-}
-
func (j *Module) addGeneratedSrcJars(path android.Path) {
j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
}
@@ -1284,10 +1293,10 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
- localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
+ localHeaderJars, _, preJarjarHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
extraCombinedJars)
- combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
+ combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, preJarjarHeaderJarFile, jarName, "turbine", false)
if jarjared {
localHeaderJars = android.Paths{combinedHeaderJarFile}
transitiveStaticLibsHeaderJars = nil
@@ -1301,6 +1310,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
return nil
}
j.headerJarFile = combinedHeaderJarFile
+ if deps.headerJarOverride.Valid() {
+ j.headerJarFile = deps.headerJarOverride.Path()
+ }
if len(localHeaderJars) > 0 {
ctx.CheckbuildFile(localHeaderJars...)
@@ -1312,6 +1324,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.outputFile = j.headerJarFile
return &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ LocalHeaderJarsPreJarjar: android.PathsIfNonNil(preJarjarHeaderJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
@@ -1323,6 +1336,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
SdkVersion: j.SdkVersion(ctx),
+ OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version,
+ Installable: BoolDefault(j.properties.Installable, true),
}
}
@@ -1367,23 +1382,73 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
kotlincFlags = append(kotlincFlags, "-no-jdk")
}
+ var kotlincPluginFlags []string
for _, plugin := range deps.kotlinPlugins {
- kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String())
+ kotlincPluginFlags = append(kotlincPluginFlags, "-Xplugin="+plugin.String())
+ }
+ if len(kotlincPluginFlags) > 0 {
+ // optimization.
+ ctx.Variable(pctx, "kotlincPluginFlags", strings.Join(kotlincPluginFlags, " "))
+ flags.kotlincPluginFlags += "$kotlincPluginFlags"
}
flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...)
+ if deps.composePlugin.Valid() {
+ flags.composePluginFlag = "-Xplugin=" + deps.composePlugin.String()
+ ctx.Variable(pctx, "composePluginFlag", flags.composePluginFlag)
+ flags.kotlincDeps = append(flags.kotlincDeps, deps.composePlugin.Path())
+ }
+ if deps.composeEmbeddablePlugin.Valid() {
+ flags.composeEmbeddablePluginFlag = "-Xplugin=" + deps.composeEmbeddablePlugin.String()
+ ctx.Variable(pctx, "composeEmbeddablePluginFlag", flags.composeEmbeddablePluginFlag)
+ flags.kotlincDeps = append(flags.kotlincDeps, deps.composeEmbeddablePlugin.Path())
+ }
+
+ // TODO(b/403236545): Remove this once the Kotlin compiler version is >= 2.2.0.
+ if j.useCompose(ctx) {
+ kotlincFlags = append(kotlincFlags, "-P", "plugin:androidx.compose.compiler.plugins.kotlin:featureFlag=+OptimizeNonSkippingGroups")
+ }
+
if len(kotlincFlags) > 0 {
+ // Flags with `-J` as a prefix are meant to be passed to java directly.
+ // When running the kotlin-incremental-client, flags are first parsed by a bash
+ // script that eagerly takes all the leading arguments that start with `-J` and feeds
+ // them to java. Any `-J` arguments that occur elsewhere (i.e. after a non-J argument)
+ // fail to pass through to java as expected.
+ slices.SortStableFunc(kotlincFlags, func(a, b string) int {
+ aHasPrefix := strings.HasPrefix(a, "-J")
+ bHasPrefix := strings.HasPrefix(b, "-J")
+
+ // If only a has the prefix, it should come before b
+ if aHasPrefix && !bHasPrefix {
+ return -1
+ } else if bHasPrefix && !aHasPrefix {
+ return 1
+ }
+ return 0 // Otherwise maintain their order
+ })
// optimization.
ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
flags.kotlincFlags += "$kotlincFlags"
}
+ incrementalKotlin := j.incrementalKotlin(ctx.Config())
+
// Collect common .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...)
flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...)
+ kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
+ kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
+
+ kotlinCompileData := KotlinCompileData{
+ diffFile: kotlinJar.ReplaceExtension(ctx, "source_diff"),
+ pcStateFileNew: kotlinJar.ReplaceExtension(ctx, "pc_state.new"),
+ pcStateFilePrior: kotlinJar.ReplaceExtension(ctx, "pc_state"),
+ }
+
if len(flags.processorPath) > 0 {
// Use kapt for annotation processing
kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
@@ -1396,9 +1461,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
flags.processors = nil
}
- kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
- kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
- j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
+ j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags, kotlinCompileData, incrementalKotlin)
if ctx.Failed() {
return nil
}
@@ -1421,6 +1484,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
var localHeaderJars android.Paths
var shardingHeaderJars android.Paths
var repackagedHeaderJarFile android.Path
+ var combinedHeaderJarFile android.Path
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
enableSharding = true
@@ -1432,9 +1496,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
extraJars := slices.Clone(kotlinHeaderJars)
extraJars = append(extraJars, extraCombinedJars...)
- var combinedHeaderJarFile android.Path
- localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
- shardingHeaderJars = localHeaderJars
+ localHeaderJars, shardingHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
var jarjared bool
j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false)
@@ -1464,6 +1526,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
break
}
}
+
+ // turbine is disabled when API generating APs are present, in which case,
+ // we would want to process annotations before moving to incremental javac
+ var genAnnoSrcJar android.Path
+ if ctx.Device() && ctx.Config().PartialCompileFlags().Enable_inc_javac && disableTurbine {
+ srcJarsForTurbine := slices.Clone(srcJars)
+ if len(flags.processorPath) > 0 {
+ genAnnoSrcJar, _ = j.generateJavaAnnotations(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, nil)
+ flags.processorPath = nil
+ flags.processors = nil
+ srcJarsForTurbine = append(srcJarsForTurbine, genAnnoSrcJar)
+ }
+ // turbine was disabled, lets run it now
+ turbineExtraJars := slices.Clone(kotlinHeaderJars)
+ turbineExtraJars = append(turbineExtraJars, extraCombinedJars...)
+ _, shardingHeaderJars, _ = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJarsForTurbine, deps, flags, jarName, turbineExtraJars)
+ }
+
var extraJarDeps android.Paths
if Bool(j.properties.Errorprone.Enabled) {
// If error-prone is enabled, enable errorprone flags on the regular
@@ -1486,7 +1566,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar")
- transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil,
+ transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, false, errorproneFlags, nil,
"errorprone", "errorprone")
extraJarDeps = append(extraJarDeps, errorprone)
@@ -1503,7 +1583,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
- nil, flags, extraJarDeps)
+ nil, nil, flags, extraJarDeps, nil)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
localImplementationJars = append(localImplementationJars, classes)
}
@@ -1516,13 +1596,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5)
for idx, shardSrcJars := range shardSrcJarsList {
classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
- nil, shardSrcJars, flags, extraJarDeps)
+ nil, shardSrcJars, nil, flags, extraJarDeps, nil)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
localImplementationJars = append(localImplementationJars, classes)
}
}
} else {
- classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
+ classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, shardingHeaderJars, flags, extraJarDeps, genAnnoSrcJar)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
localImplementationJars = append(localImplementationJars, classes)
}
@@ -1685,10 +1765,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
if j.ravenizer.enabled {
ravenizerInput := outputFile
ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", "", jarName)
- ravenizerArgs := ""
+
+ ravenizerArgs := j.properties.Ravenizer.Flags
if proptools.Bool(j.properties.Ravenizer.Strip_mockito) {
- ravenizerArgs = "--strip-mockito"
+ ravenizerArgs = append(ravenizerArgs, "--strip-mockito")
}
+
TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs)
outputFile = ravenizerOutput
localImplementationJars = android.Paths{ravenizerOutput}
@@ -1835,7 +1917,11 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
if dexArtProfileOutput != nil {
- j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput)
+ if concretePtr, ok := dexArtProfileOutput.(*android.OutputPath); ok {
+ if concretePtr != nil {
+ j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput)
+ }
+ }
}
// merge dex jar with resources if necessary
@@ -1864,11 +1950,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
// Dexpreopting
- libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
- if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
- libName = strings.TrimSuffix(libName, ".impl")
+ if dexArtProfileOutput != nil {
+ libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
+ if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") {
+ libName = strings.TrimSuffix(libName, ".impl")
+ }
+ j.dexpreopt(ctx, libName, dexOutputFile)
}
- j.dexpreopt(ctx, libName, dexOutputFile)
outputFile = dexOutputFile
@@ -1905,7 +1993,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data)
- if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
+ if !apexInfo.IsForPlatform() && ctx.Config().HasUnbundledBuildApps() {
j.linter.buildModuleReportZip = true
}
j.linter.lint(ctx)
@@ -1925,11 +2013,16 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
j.outputFile = outputFile.WithoutRel()
+ if deps.headerJarOverride.Valid() {
+ j.headerJarFile = deps.headerJarOverride.Path()
+ }
return &JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ LocalHeaderJarsPreJarjar: android.PathsIfNonNil(combinedHeaderJarFile),
+ RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
LocalHeaderJars: localHeaderJars,
+ KotlinHeaderJars: kotlinHeaderJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
@@ -1946,11 +2039,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
- JacocoReportClassesFile: j.jacocoReportClassesFile,
+ JacocoInfo: j.jacocoInfo,
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
SdkVersion: j.SdkVersion(ctx),
OutputFile: j.outputFile,
+ OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version,
+ Installable: BoolDefault(j.properties.Installable, true),
}
}
@@ -2018,7 +2113,7 @@ func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
}
func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
- srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path {
+ srcFiles, srcJars, localHeaderJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths, genAnnoSrcJar android.Path) android.Path {
kzipName := pathtools.ReplaceExtension(jarName, "kzip")
annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar")
@@ -2029,7 +2124,13 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i
}
classes := android.PathForModuleOut(ctx, "javac", jarName)
- TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
+ // enable incremental javac when corresponding flags are enabled and
+ // header jars are present
+ if ctx.Config().PartialCompileFlags().Enable_inc_javac && len(localHeaderJars) > 0 {
+ TransformJavaToClassesInc(ctx, classes, srcFiles, srcJars, localHeaderJars, annoSrcJar, flags, extraJarDeps, genAnnoSrcJar)
+ } else {
+ TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
+ }
if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() {
extractionFile := android.PathForModuleOut(ctx, kzipName)
@@ -2044,6 +2145,20 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i
return classes
}
+func (j *Module) generateJavaAnnotations(ctx android.ModuleContext, jarName string, idx int,
+ srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) (android.Path, android.Path) {
+
+ annoSrcJar := android.PathForModuleOut(ctx, "javac-apt", "anno.srcjar")
+ if idx >= 0 {
+ annoSrcJar = android.PathForModuleOut(ctx, "javac-apt", "anno-"+strconv.Itoa(idx)+".srcjar")
+ jarName += strconv.Itoa(idx)
+ }
+
+ classes := android.PathForModuleOut(ctx, "javac-apt", jarName)
+ GenerateJavaAnnotations(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps)
+ return annoSrcJar, classes
+}
+
// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
// since some of these flags may be used internally.
func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
@@ -2073,7 +2188,21 @@ func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
deps deps, flags javaBuilderFlags, jarName string,
- extraJars android.Paths) (localHeaderJars android.Paths, combinedHeaderJar android.Path) {
+ extraJars android.Paths) (localHeaderJars, localHeaderJarsForSharding android.Paths, combinedHeaderJar android.Path) {
+
+ if deps.headerJarOverride.Valid() {
+ // If we are sharding, we need the pre-jarjar override path; localHeaderJars always
+ // needs the jarjared version.
+ localHeaderJars = append(android.Paths{deps.headerJarOverride.Path()}, extraJars...)
+ var headerJar android.Path
+ if deps.headerJarOverridePreJarjar.Valid() {
+ headerJar = deps.headerJarOverridePreJarjar.Path()
+ } else {
+ headerJar = deps.headerJarOverride.Path()
+ }
+ localHeaderJarsForSharding = append(android.Paths{headerJar}, extraJars...)
+ return localHeaderJars, localHeaderJarsForSharding, deps.headerJarOverride.Path()
+ }
if len(srcFiles) > 0 || len(srcJars) > 0 {
// Compile java sources into turbine.jar.
@@ -2089,13 +2218,14 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
jars := depSet.ToList()
+ var combinedHeaderJarOutputPath android.WritablePath
// we cannot skip the combine step for now if there is only one jar
// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
- combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ combinedHeaderJarOutputPath = android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
- return localHeaderJars, combinedHeaderJarOutputPath
+ return localHeaderJars, localHeaderJars, combinedHeaderJarOutputPath
}
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
@@ -2106,7 +2236,12 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs)
- j.jacocoReportClassesFile = jacocoReportClassesFile
+ j.jacocoInfo.ReportClassesFile = jacocoReportClassesFile
+ j.jacocoInfo.ModuleName = android.ModuleNameWithPossibleOverride(ctx)
+ // Allow overriding the class before instrument() is called
+ if j.jacocoInfo.Class == "" {
+ j.jacocoInfo.Class = "JAVA_LIBRARIES"
+ }
return instrumentedJar
}
@@ -2251,8 +2386,8 @@ func (j *Module) Stem() string {
return j.stem
}
-func (j *Module) JacocoReportClassesFile() android.Path {
- return j.jacocoReportClassesFile
+func (j *Module) JacocoInfo() JacocoInfo {
+ return j.jacocoInfo
}
func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
@@ -2463,6 +2598,15 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
+ case headerJarOverrideTag:
+ if dep.HeaderJars == nil {
+ ctx.ModuleErrorf("%s does not provide header jars", otherName)
+ } else if len(dep.HeaderJars) > 1 {
+ ctx.ModuleErrorf("%s provides too many header jars", otherName)
+ } else {
+ deps.headerJarOverride = android.OptionalPathForPath(dep.HeaderJars[0])
+ deps.headerJarOverridePreJarjar = android.OptionalPathForPath(dep.LocalHeaderJarsPreJarjar[0])
+ }
case java9LibTag:
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
@@ -2519,6 +2663,18 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
} else {
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
+ case composeEmbeddablePluginTag:
+ if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
+ deps.composeEmbeddablePlugin = android.OptionalPathForPath(dep.ImplementationAndResourcesJars[0])
+ } else {
+ ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
+ }
+ case composePluginTag:
+ if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
+ deps.composePlugin = android.OptionalPathForPath(dep.ImplementationAndResourcesJars[0])
+ } else {
+ ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
+ }
case kotlinPluginTag:
if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok {
deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
@@ -2556,6 +2712,8 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case staticLibTag:
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
}
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, DroidStubsInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigProtoFiles...)
} else {
switch tag {
case bootClasspathTag:
@@ -2645,6 +2803,7 @@ const (
RenameUseExclude
)
+// @auto-generate: gob
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
@@ -2669,12 +2828,11 @@ var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath"
func init() {
android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
-
- gob.Register(BaseJarJarProviderData{})
}
// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
// whether they are java modules or not.
+// @auto-generate: gob
type BaseJarJarProviderData struct {
JarJarProviderData JarJarProviderData
}
@@ -2849,6 +3007,15 @@ func (this Module) GetDebugString() string {
// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to
// us, and if it's been set, apply the jarjar_prefix property to rename them.
func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData {
+
+ // Stop collect jarjar_prefix jarjar rules if the module has test sdk scope.
+ // If a module uses test API scope, which means in its source code and static dependencies
+ // it could only use API exposed through the test surface. So it should not apply the jarjar
+ // rules set by any bootclass path jar
+ if ctx.Config().ReleaseJarjarFlagsInFramework() && module.SdkVersion(ctx).Kind == android.SdkTest {
+ return nil
+ }
+
// Gather repackage information from deps
result := collectDirectDepsProviders(ctx)
diff --git a/java/base_gob_enc.go b/java/base_gob_enc.go
new file mode 100644
index 000000000..a99c98670
--- /dev/null
+++ b/java/base_gob_enc.go
@@ -0,0 +1,89 @@
+// Code generated by go run gob_gen.go; DO NOT EDIT.
+
+package java
+
+import (
+ "bytes"
+ "github.com/google/blueprint/gobtools"
+)
+
+func init() {
+ JarJarProviderDataGobRegId = gobtools.RegisterType(func() gobtools.CustomDec { return new(JarJarProviderData) })
+ BaseJarJarProviderDataGobRegId = gobtools.RegisterType(func() gobtools.CustomDec { return new(BaseJarJarProviderData) })
+}
+
+func (r JarJarProviderData) Encode(buf *bytes.Buffer) error {
+ var err error
+
+ if err = gobtools.EncodeSimple(buf, int32(len(r.Rename))); err != nil {
+ return err
+ }
+ for k, v := range r.Rename {
+ if err = gobtools.EncodeString(buf, k); err != nil {
+ return err
+ }
+ if err = gobtools.EncodeString(buf, v); err != nil {
+ return err
+ }
+ }
+ return err
+}
+
+func (r *JarJarProviderData) Decode(buf *bytes.Reader) error {
+ var err error
+
+ var val1 int32
+ err = gobtools.DecodeSimple[int32](buf, &val1)
+ if err != nil {
+ return err
+ }
+ if val1 > 0 {
+ r.Rename = make(map[string]string, val1)
+ for val2 := 0; val2 < int(val1); val2++ {
+ var k string
+ var v string
+ err = gobtools.DecodeString(buf, &k)
+ if err != nil {
+ return err
+ }
+ err = gobtools.DecodeString(buf, &v)
+ if err != nil {
+ return err
+ }
+ r.Rename[k] = v
+ }
+ }
+
+ return err
+}
+
+var JarJarProviderDataGobRegId int16
+
+func (r JarJarProviderData) GetTypeId() int16 {
+ return JarJarProviderDataGobRegId
+}
+
+func (r BaseJarJarProviderData) Encode(buf *bytes.Buffer) error {
+ var err error
+
+ if err = r.JarJarProviderData.Encode(buf); err != nil {
+ return err
+ }
+ return err
+}
+
+func (r *BaseJarJarProviderData) Decode(buf *bytes.Reader) error {
+ var err error
+
+ if err = r.JarJarProviderData.Decode(buf); err != nil {
+ return err
+ }
+
+ return err
+}
+
+var BaseJarJarProviderDataGobRegId int16
+
+func (r BaseJarJarProviderData) GetTypeId() int16 {
+ return BaseJarJarProviderDataGobRegId
+}
diff --git a/java/boot_jars.go b/java/boot_jars.go
index 3c3bd550c..75a35f13c 100644
--- a/java/boot_jars.go
+++ b/java/boot_jars.go
@@ -21,11 +21,18 @@ import (
// isActiveModule returns true if the given module should be considered for boot
// jars, i.e. if it's enabled and the preferred one in case of source and
// prebuilt alternatives.
-func isActiveModule(ctx android.ConfigurableEvaluatorContext, module android.Module) bool {
- if !module.Enabled(ctx) {
- return false
+func isActiveModule(ctx android.ModuleContext, module android.ModuleOrProxy) bool {
+ if android.EqualModules(ctx.Module(), module) {
+ if !ctx.Module().Enabled(ctx) {
+ return false
+ }
+ } else {
+ info := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
+ if !info.Enabled {
+ return false
+ }
}
- return android.IsModulePreferred(module)
+ return android.IsModulePreferredProxy(ctx, module)
}
// buildRuleForBootJarsPackageCheck generates the build rule to perform the boot jars package
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index 98fb417d0..6c82d330c 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -71,8 +71,8 @@ func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex st
// gatherFragments collects fragments that are direct dependencies of this module, as well as
// any fragments in apexes via the dependency on the apex. It returns a list of the fragment
// modules and map from apex name to the fragment in that apex.
-func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[string]android.Module) {
- var fragments []android.Module
+func gatherFragments(ctx android.BaseModuleContext) ([]android.ModuleProxy, map[string]android.ModuleProxy) {
+ var fragments []android.ModuleProxy
type fragmentInApex struct {
module string
@@ -82,7 +82,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin
var fragmentsInApexes []fragmentInApex
// Find any direct dependencies, as well as a list of the modules in apexes.
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
t := ctx.OtherModuleDependencyTag(module)
if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
if bcpTag.moduleInApex != "" {
@@ -93,13 +93,13 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin
}
})
- fragmentsMap := make(map[string]android.Module)
+ fragmentsMap := make(map[string]android.ModuleProxy)
for _, fragmentInApex := range fragmentsInApexes {
- var found android.Module
+ var found android.ModuleProxy
// Find a desired module in an apex.
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
t := ctx.OtherModuleDependencyTag(child)
- if parent == ctx.Module() {
+ if android.EqualModules(parent, ctx.Module()) {
if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment && ctx.OtherModuleName(child) == fragmentInApex.apex {
// This is the dependency from this module to the apex, recurse into it.
return true
@@ -112,7 +112,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin
return false
} else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == fragmentInApex.module {
// This is the desired module inside the apex.
- if found != nil && child != found {
+ if !found.IsNil() && child != found {
panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
fragmentInApex.module, fragmentInApex.apex, found, child))
}
@@ -120,7 +120,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin
}
return false
})
- if found != nil {
+ if !found.IsNil() {
if existing, exists := fragmentsMap[fragmentInApex.apex]; exists {
ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", fragmentInApex.apex, fragmentInApex.module, existing)
} else {
@@ -137,9 +137,10 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin
// gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was
// added by addDependencyOntoApexModulePair.
-func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType bootclasspathDependencyTagType) ([]android.Module, map[android.Module]string) {
- var modules []android.Module
- modulesToApex := make(map[android.Module]string)
+func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext,
+ tagType bootclasspathDependencyTagType) ([]android.ModuleProxy, map[android.ModuleProxy]string) {
+ var modules []android.ModuleProxy
+ modulesToApex := make(map[android.ModuleProxy]string)
type moduleInApex struct {
module string
@@ -148,7 +149,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot
var modulesInApexes []moduleInApex
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
t := ctx.OtherModuleDependencyTag(module)
if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType {
if bcpTag.moduleInApex != "" {
@@ -160,10 +161,10 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot
})
for _, moduleInApex := range modulesInApexes {
- var found android.Module
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ var found android.ModuleProxy
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
t := ctx.OtherModuleDependencyTag(child)
- if parent == ctx.Module() {
+ if android.EqualModules(parent, ctx.Module()) {
if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex {
// recurse into the apex
return true
@@ -177,7 +178,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot
} else if IsBootclasspathFragmentContentDepTag(t) {
return false
} else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
- if found != nil && child != found {
+ if !found.IsNil() && child != found {
panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
moduleInApex.module, moduleInApex.apex, found, child))
}
@@ -185,7 +186,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot
}
return false
})
- if found != nil {
+ if !found.IsNil() {
modules = append(modules, found)
if existing, exists := modulesToApex[found]; exists && existing != moduleInApex.apex {
ctx.ModuleErrorf("module %s is in two apexes, %s and %s", moduleInApex.module, existing, moduleInApex.apex)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index a09416dc4..4505a40c4 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -41,7 +41,14 @@ func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContex
ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory)
}
-type BootclasspathFragmentInfo struct{}
+type BootclasspathFragmentInfo struct {
+ ImageName *string
+ Contents []string
+ ApiStubLibs []string
+ CorePlatformApiStubLibs []string
+ Fragments []ApexVariantReference
+ ProfilePathOnHost android.Path
+}
var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]()
@@ -73,10 +80,10 @@ func (b bootclasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() b
// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
// they were specified using java_boot_libs or java_sdk_libs.
-func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType {
// If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
// property, otherwise treat if it was specified in the java_boot_libs property.
- if javaSdkLibrarySdkMemberType.IsInstance(child) {
+ if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) {
return javaSdkLibrarySdkMemberType
}
@@ -267,7 +274,8 @@ 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, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
+ produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.ModuleProxy, fragments []android.ModuleProxy,
+ input HiddenAPIFlagInput) *HiddenAPIOutput
// getProfilePath returns the path to the boot image profile.
getProfilePath() android.Path
@@ -392,7 +400,7 @@ type BootclasspathFragmentApexContentInfo struct {
// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
//
// The dex boot jar is one which has had hidden API encoding performed on it.
-func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) {
+func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.ModuleOrProxy) (android.Path, error) {
// A bootclasspath_fragment cannot use a prebuilt library so Name() will return the base name
// without a prebuilt_ prefix so is safe to use as the key for the contentModuleDexJarPaths.
name := module.Name()
@@ -530,9 +538,13 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Generate classpaths.proto config
b.generateClasspathProtoBuildActions(ctx)
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"FAKE"}
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
+
// Gather the bootclasspath fragment's contents.
- var contents []android.Module
- ctx.VisitDirectDeps(func(module android.Module) {
+ var contents []android.ModuleProxy
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if IsBootclasspathFragmentContentDepTag(tag) {
contents = append(contents, module)
@@ -544,7 +556,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
- if android.IsModulePrebuilt(ctx.Module()) {
+ if android.IsModulePrebuilt(ctx, ctx.Module()) {
b.profilePath = ctx.Module().(*PrebuiltBootclasspathFragmentModule).produceBootImageProfile(ctx)
} else {
b.profilePath = b.produceBootImageProfileFromSource(ctx, contents, hiddenAPIOutput.EncodedBootDexFilesByModule)
@@ -562,14 +574,21 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
b.HideFromMake()
}
- android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{})
+ android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{
+ ImageName: b.properties.Image_name,
+ Contents: b.properties.Contents.GetOrDefault(ctx, nil),
+ ApiStubLibs: b.properties.Api.Stub_libs.GetOrDefault(ctx, nil),
+ CorePlatformApiStubLibs: b.properties.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil),
+ Fragments: b.properties.Fragments,
+ ProfilePathOnHost: b.profilePath,
+ })
}
// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an
// empty string if this module should not provide a boot image profile.
func (b *BootclasspathFragmentModule) getProfileProviderApex(ctx android.BaseModuleContext) string {
// Only use the profile from the module that is preferred.
- if !isActiveModule(ctx, ctx.Module()) {
+ if !android.IsModulePreferredProxy(ctx, ctx.Module()) {
return ""
}
@@ -646,7 +665,7 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
// TODO(b/202896428): Add better way to handle this.
_, unknown = android.RemoveFromList("android.car-module", unknown)
if isApexVariant(ctx) && len(unknown) > 0 {
- if android.IsModulePrebuilt(ctx.Module()) {
+ if android.IsModulePrebuilt(ctx, ctx.Module()) {
// prebuilt bcpf. the validation of this will be done at the top-level apex
providerClasspathFragmentValidationInfoProvider(ctx, unknown)
} else if !disableSourceApexVariant(ctx) && android.IsModulePreferred(ctx.Module()) {
@@ -676,7 +695,8 @@ func providerClasspathFragmentValidationInfoProvider(ctx android.ModuleContext,
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
-func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput {
+func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.ModuleProxy,
+ fragments []android.ModuleProxy) *HiddenAPIOutput {
// Create hidden API input structure.
input := b.createHiddenAPIFlagInput(ctx, contents, fragments)
@@ -720,7 +740,8 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived
// from the properties on this module and its dependencies.
-func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) HiddenAPIFlagInput {
+func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.ModuleProxy,
+ fragments []android.ModuleProxy) HiddenAPIFlagInput {
// Merge the HiddenAPIInfo from all the fragment dependencies.
dependencyHiddenApiInfo := newHiddenAPIInfo()
dependencyHiddenApiInfo.mergeFromFragmentDeps(ctx, fragments)
@@ -752,7 +773,7 @@ func (b *BootclasspathFragmentModule) isTestFragment() bool {
// 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 {
+func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.ModuleContext, contents []android.ModuleProxy, 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.
flagOutput := hiddenAPIFlagRulesForBootclasspathFragment(ctx, bootDexInfoByModule, contents, input, suffix)
@@ -781,7 +802,8 @@ func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.Mod
// 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 {
+func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.ModuleProxy,
+ fragments []android.ModuleProxy, input HiddenAPIFlagInput) *HiddenAPIOutput {
// Gather information about the boot dex files for the boot libraries provided by this fragment.
bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
@@ -805,11 +827,12 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
// 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{}
+ contentsForSdkSnapshot := []android.ModuleProxy{}
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)
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
+ minApiLevel := android.MinApiLevelForSdkSnapshot(commonInfo)
if minApiLevel.GreaterThan(targetApiLevel) {
continue
}
@@ -843,7 +866,8 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
}
// produceBootImageProfileFromSource builds the boot image profile from the source if it is required.
-func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext, contents []android.Module, modules bootDexJarByModule) android.WritablePath {
+func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext,
+ contents []android.ModuleProxy, modules bootDexJarByModule) android.WritablePath {
apex := b.getProfileProviderApex(ctx)
if apex == "" {
return nil
@@ -897,8 +921,8 @@ func (b *bootclasspathFragmentMemberType) AddDependencies(ctx android.SdkDepende
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (b *bootclasspathFragmentMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*BootclasspathFragmentModule)
+func (b *bootclasspathFragmentMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ _, ok := android.OtherModuleProvider(ctx, module, BootclasspathFragmentInfoProvider)
return ok
}
@@ -958,15 +982,15 @@ type bootclasspathFragmentSdkMemberProperties struct {
Filtered_flags_path android.OptionalPath `supported_build_releases:"Tiramisu+"`
}
-func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- module := variant.(*BootclasspathFragmentModule)
+func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ mctx := ctx.SdkModuleContext()
+ module, _ := android.OtherModuleProvider(mctx, variant, BootclasspathFragmentInfoProvider)
- b.Image_name = module.properties.Image_name
- b.Contents = module.properties.Contents.GetOrDefault(ctx.SdkModuleContext(), nil)
+ b.Image_name = module.ImageName
+ b.Contents = module.Contents
// Get the hidden API information from the module.
- mctx := ctx.SdkModuleContext()
- hiddenAPIInfo, _ := android.OtherModuleProvider(mctx, module, HiddenAPIInfoForSdkProvider)
+ hiddenAPIInfo, _ := android.OtherModuleProvider(mctx, variant, HiddenAPIInfoForSdkProvider)
b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory
// Copy all the generated file paths.
@@ -982,11 +1006,11 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro
b.Filtered_flags_path = android.OptionalPathForPath(hiddenAPIInfo.FilteredFlagsPath)
// Copy stub_libs properties.
- b.Stub_libs = module.properties.Api.Stub_libs.GetOrDefault(mctx, nil)
- b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs.GetOrDefault(mctx, nil)
+ b.Stub_libs = module.ApiStubLibs
+ b.Core_platform_stub_libs = module.CorePlatformApiStubLibs
// Copy fragment properties.
- b.Fragments = module.properties.Fragments
+ b.Fragments = module.Fragments
}
func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -1108,7 +1132,8 @@ 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, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext,
+ contents []android.ModuleProxy, fragments []android.ModuleProxy, input HiddenAPIFlagInput) *HiddenAPIOutput {
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
if src == nil {
return defaultPath
diff --git a/java/builder.go b/java/builder.go
index dff0032d8..3251dfd9c 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -20,6 +20,7 @@ package java
import (
"path/filepath"
+ "slices"
"strconv"
"strings"
@@ -33,13 +34,101 @@ import (
var (
pctx = android.NewPackageContext("android/soong/java")
+ // Unzips java src files from supplied jars into a directory provided.
+ extractSrcJars = pctx.AndroidStaticRule("javac-extract-srcJars",
+ blueprint.RuleParams{
+ Command: `rm -rf "$extractDir" && mkdir -p "$extractDir" && ${config.ZipSyncCmd} -d "$extractDir" -l "$out" -f "*.java" $jars`,
+ CommandDeps: []string{
+ "${config.ZipSyncCmd}",
+ },
+ }, "extractDir", "jars",
+ )
+
+ // Removes all outputs of inc-javac rule
+ javacIncClean = pctx.AndroidStaticRule("javac-inc-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${srcJarDir}" "${outDir}" "${annoDir}" "${annoSrcJar}" "${builtOut}"`,
+ }, "srcJarDir", "outDir", "annoDir", "annoSrcJar", "builtOut",
+ )
+
+ // Incremental javac rule
+ // The idea of this rule is to make javac incremental, i.e. use the input and
+ // output of previous javac execution to reduce the src lists.
+ // This rule is very similar to the normal javac rule with a few differences:
+ // * Does not unzip srcJars in the rule
+ // * Does not remove the temp directories containing classes/generated sources
+ // * Saves the states of a bunch of input params, when javac executes successfully.
+ // * Runs additional tools on the output to prepare for next iteration
+ javacInc, javacIncRE = pctx.MultiCommandRemoteStaticRules("javac-inc",
+ blueprint.RuleParams{
+ Command: `rm -rf "$annoSrcJar.tmp" "$out.tmp" && ` +
+ `mkdir -p "$annoDir" && ` +
+ `if [ -s $out.rsp ] && [ -s $srcJarList ] ; then ` +
+ `echo >> $out.rsp; fi && ` +
+ `cat $srcJarList >> $out.rsp && ` +
+ `if [ -s $genAnnoSrcJarList ] ; then ` +
+ `echo >> $out.rsp && cat $genAnnoSrcJarList >> $out.rsp; fi && ` +
+ `${config.IncrementalJavacInputCmd} ` +
+ `--srcs $out.rsp --classDir $outDir --deps $javacDeps --javacTarget $out --srcDepsProto $out.proto --localHeaderJars $localHeaderJars && ` +
+ `mkdir -p "$outDir" && ` +
+ `(if [ -s $out.inc.rsp ] ; then ` +
+ `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
+ `${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` +
+ `$processorpath $processor $javacFlags $bootClasspath $classpath ` +
+ `-source $javaVersion -target $javaVersion ` +
+ `-d $outDir -s $annoDir @$out.inc.rsp ; fi ) && ` +
+ `cat $out.rem.rsp | xargs rm -f && ` +
+ `$annoSrcJarTemplate${config.SoongZipCmd} -jar -o $annoSrcJar.tmp -C $annoDir -D $annoDir && ` +
+ `$zipTemplate${config.SoongZipCmd} -jar -o $out.tmp -C $outDir -D $outDir && ` +
+ `if ! cmp -s "$out.tmp" "$out"; then mv "$out.tmp" "$out"; fi && ` +
+ `if ! cmp -s "$annoSrcJar.tmp" "$annoSrcJar"; then mv "$annoSrcJar.tmp" "$annoSrcJar"; fi && ` +
+ `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` +
+ `rm -rf $out.input.pc_state.new; fi && ` +
+ `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` +
+ `rm -rf $out.deps.pc_state.new; fi && ` +
+ `if [ -f "$out.headers.pc_state.new" ]; then mv "$out.headers.pc_state.new" "$out.headers.pc_state" && ` +
+ `rm -rf $out.headers.pc_state.new; fi && ` +
+ `if [ -f $out.rsp ] && [ -f $out ]; then ` +
+ `${config.DependencyMapperJavacCmd} --src-path $out.rsp --jar-path $out --dependency-map-path $out.proto; fi`,
+ CommandDeps: []string{
+ "${config.DependencyMapperJavacCmd}",
+ "${config.IncrementalJavacInputCmd}",
+ "${config.JavacCmd}",
+ "${config.ZipSyncCmd}",
+ },
+ CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
+ Restat: true,
+ Rspfile: "$out.rsp",
+ RspfileContent: "$in",
+ }, map[string]*remoteexec.REParams{
+ "$javaTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "javac"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$out.tmp"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$annoSrcJarTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$annoDir"},
+ OutputFiles: []string{"$annoSrcJar.tmp"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJarList", "genAnnoSrcJarList",
+ "outDir", "annoDir", "annoSrcJar", "javaVersion", "javacDeps", "localHeaderJars"}, nil)
+
// Compiling java is not conducive to proper dependency tracking. The path-matches-class-name
// requirement leads to unpredictable generated source file names, and a single .java file
// will get compiled into multiple .class files if it contains inner classes. To work around
// this, all java rules write into separate directories and then are combined into a .jar file
// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
// .srcjar files are unzipped into a temporary directory when compiled with javac.
- // TODO(b/143658984): goma can't handle the --system argument to javac.
javac, javacRE = pctx.MultiCommandRemoteStaticRules("javac",
blueprint.RuleParams{
Command: `rm -rf "$outDir" "$annoDir" "$annoSrcJar.tmp" "$srcJarDir" "$out.tmp" && ` +
@@ -312,10 +401,12 @@ var (
blueprint.RuleParams{
Command: `${aconfig} dump-cache --dedup --format=protobuf ` +
`--out ${out} ` +
- `${flags_path} ` +
+ `@$out.rsp ` +
`${filter_args} `,
- CommandDeps: []string{"${aconfig}"},
- Description: "aconfig_bool",
+ CommandDeps: []string{"${aconfig}"},
+ Description: "aconfig_bool",
+ Rspfile: "$out.rsp",
+ RspfileContent: "${flags_path}",
}, "flags_path", "filter_args")
generateMetalavaRevertAnnotationsRule = pctx.AndroidStaticRule("generateMetalavaRevertAnnotationsRule",
@@ -374,9 +465,12 @@ type javaBuilderFlags struct {
errorProneExtraJavacFlags string
errorProneProcessorPath classpath
- kotlincFlags string
- kotlincClasspath classpath
- kotlincDeps android.Paths
+ kotlincFlags string
+ kotlincPluginFlags string
+ composePluginFlag string
+ composeEmbeddablePluginFlag string
+ kotlincClasspath classpath
+ kotlincDeps android.Paths
proto android.ProtoFlags
}
@@ -387,6 +481,14 @@ func DefaultJavaBuilderFlags() javaBuilderFlags {
}
}
+func TransformJavaToClassesInc(ctx android.ModuleContext, outputFile android.WritablePath,
+ srcFiles, srcJars, headerJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths, genAnnoSrcJar android.Path) {
+
+ // Compile java sources into .class files
+ desc := "javac-inc"
+ transformJavaToClassesInc(ctx, outputFile, srcFiles, srcJars, headerJars, annoSrcJar, flags, deps, "javac", desc, genAnnoSrcJar)
+}
+
func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int,
srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) {
@@ -395,8 +497,18 @@ func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
if shardIdx >= 0 {
desc += strconv.Itoa(shardIdx)
}
+ transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, false, flags, deps, "javac", desc)
+}
+func GenerateJavaAnnotations(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int,
+ srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) {
+
+ // Generate src files from Java Annotations.
+ desc := "javac-apt"
+ if shardIdx >= 0 {
+ desc += strconv.Itoa(shardIdx)
+ }
- transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, flags, deps, "javac", desc)
+ transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, true, flags, deps, "javac-apt", desc)
}
// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
@@ -588,6 +700,153 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr
})
}
+// Similar to transformJavaToClasses, with additional tweaks to make java
+// compilation work incrementally (i.e. work with a smaller subset of src java files
+// rather than the full set)
+func transformJavaToClassesInc(ctx android.ModuleContext, outputFile android.WritablePath,
+ srcFiles, srcJars, shardingHeaderJars android.Paths, annoSrcJar android.WritablePath,
+ flags javaBuilderFlags, deps android.Paths, intermediatesDir, desc string, genAnnoSrcJar android.Path) {
+
+ javacClasspath := flags.classpath
+
+ var bootClasspath string
+ if flags.javaVersion.usesJavaModules() {
+ var systemModuleDeps android.Paths
+ bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device())
+ deps = append(deps, systemModuleDeps...)
+ javacClasspath = append(flags.java9Classpath, javacClasspath...)
+ } else {
+ deps = append(deps, flags.bootClasspath...)
+ if len(flags.bootClasspath) == 0 && ctx.Device() {
+ // explicitly specify -bootclasspath "" if the bootclasspath is empty to
+ // ensure java does not fall back to the default bootclasspath.
+ bootClasspath = `-bootclasspath ""`
+ } else {
+ bootClasspath = flags.bootClasspath.FormJavaClassPath("-bootclasspath")
+ }
+ }
+
+ deps = append(deps, flags.processorPath...)
+ deps = append(deps, javacClasspath...)
+
+ // The file containing dependencies of the current module
+ // Any change in them may warrant changes in the incremental compilation
+ // source set.
+ javacDeps := outputFile.ReplaceExtension(ctx, "jar.deps.rsp")
+ android.WriteFileRule(ctx, javacDeps, strings.Join(deps.Strings(), "\n"))
+ deps = append(deps, javacDeps)
+
+ // Add localHeader Jars in classpath, they are required for incremental compilation.
+ // These are conspicuously not added to javacDeps file, as a change in them
+ // does not warrant full re-compilation.
+ javacClasspath = append(classpath(slices.Clone(shardingHeaderJars)), javacClasspath...)
+ deps = append(deps, shardingHeaderJars...)
+ shardingHeaderRsp := outputFile.ReplaceExtension(ctx, "jar.headers.rsp")
+ android.WriteFileRule(ctx, shardingHeaderRsp, strings.Join(shardingHeaderJars.Strings(), "\n"))
+ deps = append(deps, shardingHeaderRsp)
+
+ // Doing this now, sow that they are not added to javacDeps file
+ deps = append(deps, srcJars...)
+
+ classpathArg := javacClasspath.FormJavaClassPath("-classpath")
+
+ // Keep the command line under the MAX_ARG_STRLEN limit by putting the classpath argument into an rsp file
+ // if it is too long.
+ const classpathLimit = 64 * 1024
+ if len(classpathArg) > classpathLimit {
+ classpathRspFile := outputFile.ReplaceExtension(ctx, "classpath")
+ android.WriteFileRule(ctx, classpathRspFile, classpathArg)
+ deps = append(deps, classpathRspFile)
+ classpathArg = "@" + classpathRspFile.String()
+ }
+
+ processor := "-proc:none"
+ if len(flags.processors) > 0 {
+ processor = "-processor " + strings.Join(flags.processors, ",")
+ }
+
+ srcJarDir := "srcjars"
+ outDir := "classes"
+ annoDir := "anno"
+ srcJarList := android.PathForModuleOut(ctx, intermediatesDir, srcJarDir, "list")
+ deps = append(deps, srcJarList)
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractSrcJars,
+ Description: "javacExtractSrcJars",
+ Inputs: srcJars,
+ Output: srcJarList,
+ Args: map[string]string{
+ "extractDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
+ "jars": strings.Join(srcJars.Strings(), " "),
+ },
+ })
+
+ genAnnoSrcJarList := android.PathForModuleOut(ctx, intermediatesDir, annoDir, "list")
+ deps = append(deps, genAnnoSrcJarList)
+ var jars string
+ if genAnnoSrcJar != nil {
+ jars = genAnnoSrcJar.String()
+ } else {
+ jars = ""
+ }
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractSrcJars,
+ Description: "javacExtractAnnoSrcJar",
+ Input: genAnnoSrcJar,
+ Output: genAnnoSrcJarList,
+ Args: map[string]string{
+ "extractDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(),
+ "jars": jars,
+ },
+ })
+
+ rule := javacInc
+ ctx.Build(pctx, android.BuildParams{
+ Rule: rule,
+ Description: desc,
+ Output: outputFile,
+ ImplicitOutput: annoSrcJar,
+ Inputs: srcFiles,
+ Implicits: deps,
+ Args: map[string]string{
+ "javacFlags": flags.javacFlags,
+ "bootClasspath": bootClasspath,
+ "classpath": classpathArg,
+ "processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
+ "processor": processor,
+ "srcJarList": srcJarList.String(),
+ "genAnnoSrcJarList": genAnnoSrcJarList.String(),
+ "outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
+ "annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(),
+ "annoSrcJar": annoSrcJar.String(),
+ "javaVersion": flags.javaVersion.String(),
+ "javacDeps": javacDeps.String(),
+ "localHeaderJars": shardingHeaderRsp.String(),
+ },
+ })
+
+ // The Phony Clean rule allows javac to move from incremental to full, without
+ // re-analysis by removing all the outputs of javac, triggering all rules
+ // that generate them.
+ cleanPhonyPath := android.PathForModuleOut(ctx, "dex", outputFile.String()+"-partialcompileclean").OutputPath
+ // Generate the rule for partial compile clean.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: javacIncClean,
+ Description: "javacIncClean",
+ Output: cleanPhonyPath,
+ Args: map[string]string{
+ "srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
+ "outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
+ "annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(),
+ "annoSrcJar": annoSrcJar.String(),
+ "builtOut": outputFile.String(),
+ },
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+}
+
// transformJavaToClasses takes source files and converts them to a jar containing .class files.
// srcFiles is a list of paths to sources, srcJars is a list of paths to jar files that contain
// sources. flags contains various command line flags to be passed to the compiler.
@@ -597,8 +856,11 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr
// be printed at build time. The stem argument provides the file name of the output jar, and
// suffix will be appended to various intermediate files and directories to avoid collisions when
// this function is called twice in the same module directory.
+//
+// This method can also be used to only process Annotations, without completely
+// compiling java sources.
func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
- shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath,
+ shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, onlyGenerateAnnotations bool,
flags javaBuilderFlags, deps android.Paths,
intermediatesDir, desc string) {
@@ -640,7 +902,11 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab
processor := "-proc:none"
if len(flags.processors) > 0 {
- processor = "-processor " + strings.Join(flags.processors, ",")
+ if onlyGenerateAnnotations {
+ processor = "-proc:only -processor " + strings.Join(flags.processors, ",")
+ } else {
+ processor = "-processor " + strings.Join(flags.processors, ",")
+ }
}
srcJarDir := "srcjars"
@@ -852,14 +1118,14 @@ func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePat
}
func TransformRavenizer(ctx android.ModuleContext, outputFile android.WritablePath,
- inputFile android.Path, ravenizerArgs string) {
+ inputFile android.Path, ravenizerArgs []string) {
ctx.Build(pctx, android.BuildParams{
Rule: ravenizer,
Description: "ravenizer",
Output: outputFile,
Input: inputFile,
Args: map[string]string{
- "ravenizerArgs": ravenizerArgs,
+ "ravenizerArgs": strings.Join(ravenizerArgs, " "),
},
})
}
@@ -920,6 +1186,10 @@ func (x *classpath) FormRepeatedClassPath(optName string) []string {
return flags
}
+func (x *classpath) FirstUniquePaths() classpath {
+ return classpath(android.FirstUniquePaths(x.Paths()))
+}
+
// Convert a classpath to an android.Paths
func (x *classpath) Paths() android.Paths {
return append(android.Paths(nil), (*x)...)
diff --git a/java/classpath_element.go b/java/classpath_element.go
index 4af277012..263a5f116 100644
--- a/java/classpath_element.go
+++ b/java/classpath_element.go
@@ -28,7 +28,7 @@ import (
// ClasspathElement represents a component that contributes to a classpath. That can be
// either a java module or a classpath fragment module.
type ClasspathElement interface {
- Module() android.Module
+ Module() android.ModuleProxy
String() string
}
@@ -36,11 +36,11 @@ type ClasspathElements []ClasspathElement
// ClasspathFragmentElement is a ClasspathElement that encapsulates a classpath fragment module.
type ClasspathFragmentElement struct {
- Fragment android.Module
- Contents []android.Module
+ Fragment android.ModuleProxy
+ Contents []android.ModuleProxy
}
-func (b *ClasspathFragmentElement) Module() android.Module {
+func (b *ClasspathFragmentElement) Module() android.ModuleProxy {
return b.Fragment
}
@@ -56,10 +56,10 @@ var _ ClasspathElement = (*ClasspathFragmentElement)(nil)
// ClasspathLibraryElement is a ClasspathElement that encapsulates a java library.
type ClasspathLibraryElement struct {
- Library android.Module
+ Library android.ModuleProxy
}
-func (b *ClasspathLibraryElement) Module() android.Module {
+func (b *ClasspathLibraryElement) Module() android.ModuleProxy {
return b.Library
}
@@ -118,10 +118,10 @@ type ClasspathElementContext interface {
// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]),
// ClasspathLibraryElement(framework),
// ClasspathLibraryElement(ext),
-func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module,
- libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) ClasspathElements {
+func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.ModuleProxy, fragments []android.ModuleProxy,
+ libraryToApex map[android.ModuleProxy]string, apexNameToFragment map[string]android.ModuleProxy) ClasspathElements {
- fragmentToElement := map[android.Module]*ClasspathFragmentElement{}
+ fragmentToElement := map[android.ModuleProxy]*ClasspathFragmentElement{}
elements := []ClasspathElement{}
var currentElement ClasspathElement
@@ -130,11 +130,11 @@ skipLibrary:
for _, library := range libraries {
var element ClasspathElement
if libraryApex, ok := libraryToApex[library]; ok {
- var fragment android.Module
+ var fragment android.ModuleProxy
// Make sure that the library is in only one fragment of the classpath.
if f, ok := apexNameToFragment[libraryApex]; ok {
- if fragment == nil {
+ if fragment.IsNil() {
// This is the first fragment so just save it away.
fragment = f
} else if f != fragment {
@@ -148,7 +148,7 @@ skipLibrary:
// There is no fragment associated with the library's apex.
}
- if fragment == nil {
+ if fragment.IsNil() {
ctx.ModuleErrorf("library %s is from apexes %s which have no corresponding fragment in %s",
library, []string{libraryApex}, fragments)
// Skip over this library entirely as otherwise the resulting classpath elements would
@@ -184,7 +184,7 @@ skipLibrary:
// including the library.
fragmentElement := &ClasspathFragmentElement{
Fragment: fragment,
- Contents: []android.Module{library},
+ Contents: []android.ModuleProxy{library},
}
// Store it away so we can detect when attempting to create another element for the same
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 88a8fb80a..6b9dc194a 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -104,17 +104,14 @@ type classpathJar struct {
func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string {
set := map[string]struct{}{}
for _, name := range contents {
- dep := ctx.GetDirectDepWithTag(name, tag)
- if dep == nil && ctx.Config().AllowMissingDependencies() {
+ dep := ctx.GetDirectDepProxyWithTag(name, tag)
+ if dep.IsNil() && ctx.Config().AllowMissingDependencies() {
// Ignore apex boot jars from dexpreopt if it does not exist, and missing deps are allowed.
continue
}
- set[ModuleStemForDeapexing(dep)] = struct{}{}
- if m, ok := dep.(ModuleWithStem); ok {
- set[m.Stem()] = struct{}{}
- } else {
- ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name)
- }
+ info := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
+ set[ModuleStemForDeapexing(ctx, dep)] = struct{}{}
+ set[info.Stem] = struct{}{}
}
return android.SortedKeys(set)
}
@@ -129,12 +126,15 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars
classpath: classpathType,
path: paths[i],
}
- ctx.VisitDirectDepsIf(func(m android.Module) bool {
- return m.Name() == configuredJars.Jar(i)
- }, func(m android.Module) {
- if s, ok := m.(*SdkLibrary); ok {
- minSdkVersion := s.MinSdkVersion(ctx)
- maxSdkVersion := s.MaxSdkVersion(ctx)
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
+ if m.Name() != configuredJars.Jar(i) {
+ return
+ }
+ if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
+ info := android.OtherModuleProviderOrDefault(ctx, m, JavaInfoProvider)
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
+ minSdkVersion := *commonInfo.MinSdkVersion.ApiLevel
+ maxSdkVersion := info.MaxSdkVersion
// TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current"
if minSdkVersion.Specified() {
if minSdkVersion.IsCurrent() {
diff --git a/java/config/config.go b/java/config/config.go
index fdb8d7886..3538aa155 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -160,6 +160,9 @@ func init() {
pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
pctx.HostBinToolVariable("FindInputDeltaCmd", "find_input_delta")
+ pctx.HostBinToolVariable("IncrementalJavacInputCmd", "incremental_javac_input")
+ pctx.HostBinToolVariable("IncrementalDexInputCmd", "incremental_dex_input")
+ pctx.HostBinToolVariable("DependencyMapperJavacCmd", "dependency-mapper")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh")
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index ffb025d9c..bbf580253 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -26,6 +26,7 @@ var (
)
func init() {
+ pctx.HostBinToolVariable("KotlinIncrementalClientBinary", "kotlin-incremental-client")
pctx.SourcePathVariable("KotlincCmd", "external/kotlinc/bin/kotlinc")
pctx.SourcePathVariable("KotlinCompilerJar", "external/kotlinc/lib/kotlin-compiler.jar")
pctx.SourcePathVariable("KotlinPreloaderJar", "external/kotlinc/lib/kotlin-preloader.jar")
@@ -33,6 +34,7 @@ func init() {
pctx.SourcePathVariable("KotlinScriptRuntimeJar", "external/kotlinc/lib/kotlin-script-runtime.jar")
pctx.SourcePathVariable("KotlinTrove4jJar", "external/kotlinc/lib/trove4j.jar")
pctx.SourcePathVariable("KotlinKaptJar", "external/kotlinc/lib/kotlin-annotation-processing.jar")
+ pctx.SourcePathVariable("KotlinKaptEmbeddableJar", "external/kotlinc/lib/kotlin-annotation-processing-embeddable-2.1.10.jar")
pctx.SourcePathVariable("KotlinAnnotationJar", "external/kotlinc/lib/annotations-13.0.jar")
pctx.SourcePathVariable("KotlinStdlibJar", KotlinStdlibJar)
pctx.SourcePathVariable("KotlinAbiGenPluginJar", "external/kotlinc/lib/jvm-abi-gen.jar")
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 04def3e28..283d04598 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -102,7 +102,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
var transitiveImplementationJars []depset.DepSet[android.Path]
var transitiveResourceJars []depset.DepSet[android.Path]
- ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(deviceHostConverterDepTag, func(m android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
d.headerJars = append(d.headerJars, dep.HeaderJars...)
d.implementationJars = append(d.implementationJars, dep.ImplementationJars...)
@@ -158,6 +158,21 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
setExtraJavaInfo(ctx, d, javaInfo)
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ if ctx.Os() != android.Windows { // Make does not support Windows Java modules
+ if d.combinedImplementationJar != nil {
+ ctx.CheckbuildFile(d.combinedImplementationJar)
+ }
+ if d.combinedHeaderJar != nil {
+ ctx.CheckbuildFile(d.combinedHeaderJar)
+ }
+ }
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if d.combinedImplementationJar != nil {
+ moduleInfoJSON.ClassesJar = []string{d.combinedImplementationJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (d *DeviceHostConverter) HeaderJars() android.Paths {
@@ -184,10 +199,6 @@ func (d *DeviceHostConverter) ClassLoaderContexts() dexpreopt.ClassLoaderContext
return nil
}
-func (d *DeviceHostConverter) JacocoReportClassesFile() android.Path {
- return nil
-}
-
func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
diff --git a/java/dex.go b/java/dex.go
index e3058e9bf..fa38d6131 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -15,6 +15,8 @@
package java
import (
+ "fmt"
+ "path/filepath"
"strconv"
"strings"
@@ -25,6 +27,10 @@ import (
"android/soong/remoteexec"
)
+func init() {
+ pctx.HostBinToolVariable("symbols_map", "symbols_map")
+}
+
type DexProperties struct {
// If set to true, compile dex regardless of installable. Defaults to false.
Compile_dex *bool
@@ -80,9 +86,10 @@ type DexProperties struct {
Shrink *bool
// If true, optimize bytecode. Defaults to false.
- Optimize *bool
+ Optimize proptools.Configurable[bool] `android:"replace_instead_of_append"`
- // If true, obfuscate bytecode. Defaults to false.
+ // If true, obfuscate bytecode by renaming packages, classes, and members.
+ // Defaults to false.
Obfuscate *bool
// If true, do not use the flag files generated by aapt that automatically keep
@@ -135,6 +142,11 @@ type DexProperties struct {
// TODO(b/212737576): Handle this implicitly using bottom-up deps mutation and implicit
// creation of a proxy `.impl` library.
Trace_references_from proptools.Configurable[[]string] `android:"arch_variant"`
+
+ // Add libraries using `--classpath` instead of `--libs`, to allow overrides. This
+ // should normally not be used, but can be necessary when running R8 on the boot
+ // classpath itself.
+ Import_libraries_as_classpath *bool
}
// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -182,10 +194,125 @@ func (d *DexProperties) optimizedResourceShrinkingEnabled(ctx android.ModuleCont
return d.resourceShrinkingEnabled(ctx) && BoolDefault(d.Optimize.Optimized_shrink_resources, ctx.Config().UseOptimizedResourceShrinkingByDefault())
}
-func (d *dexer) optimizeOrObfuscateEnabled(ctx android.EarlyModuleContext) bool {
- return d.effectiveOptimizeEnabled(ctx) && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
+func (d *dexer) optimizeOrObfuscateEnabled(ctx android.ModuleContext) bool {
+ return d.effectiveOptimizeEnabled(ctx) && (d.dexProperties.Optimize.Optimize.GetOrDefault(ctx, false) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
}
+// Removes all outputs of d8Inc rule
+var d8IncClean = pctx.AndroidStaticRule("d8Inc-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${builtOut}" "${d8Deps}"`,
+ }, "outDir", "d8Flags", "d8Deps", "zipFlags", "mergeZipsFlags", "builtOut",
+)
+
+var d8Inc, d8IncRE = pctx.MultiCommandRemoteStaticRules("d8Inc",
+ blueprint.RuleParams{
+ Command: `mkdir -p "$outDir" "$outDir/packages" && ` +
+ `${config.IncrementalDexInputCmd} ` +
+ `--classesJar $in --dexTarget $out --deps $d8Deps --outputDir $outDir --packageOutputDir $outDir/packages && ` +
+ `$d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in --packages $out.rsp --mod-packages $out.inc.rsp --package-output $outDir/packages && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` +
+ `rm -rf $out.input.pc_state.new; fi && ` +
+ `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` +
+ `rm -rf $out.deps.pc_state.new; fi && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar"`,
+ CommandDeps: []string{
+ "${config.IncrementalDexInputCmd}",
+ "${config.D8Cmd}",
+ "${config.SoongZipCmd}",
+ "${config.MergeZipsCmd}",
+ },
+ }, map[string]*remoteexec.REParams{
+ "$d8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "d8"},
+ Inputs: []string{"${config.D8Jar}"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags", "d8Deps"}, nil)
+
+// Include all of the args for d8IncR8, so that we can generate the partialcompileclean target's build using the same list.
+var d8IncR8Clean = pctx.AndroidStaticRule("d8Incr8-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` +
+ `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut} ${d8Deps}`,
+ }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut",
+ "d8Flags", "d8Deps", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits",
+)
+
+var d8IncR8, d8IncR8RE = pctx.MultiCommandRemoteStaticRules("d8Incr8",
+ blueprint.RuleParams{
+ Command: `mkdir -p "$outDir" "$outDir/packages" && ` +
+ `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` +
+ `mkdir -p $$(dirname ${outUsage}) && ` +
+ `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` +
+ ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` +
+ ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` +
+ ` done && ` +
+ ` ${config.IncrementalDexInputCmd} --classesJar $in --dexTarget $out --deps $d8Deps --outputDir $outDir --packageOutputDir $outDir/packages && ` +
+ ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in --packages $out.rsp --mod-packages $out.inc.rsp --package-output $outDir/packages; ` +
+ `else ` +
+ ` rm -rf "$outDir" && mkdir -p "$outDir" && ` +
+ ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` +
+ ` --no-data-resources ` +
+ ` -printmapping ${outDict} ` +
+ ` -printconfiguration ${outConfig} ` +
+ ` -printusage ${outUsage} ` +
+ ` --deps-file ${out}.d && ` +
+ ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` +
+ `fi && ` +
+ `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` +
+ `rm -rf ${outUsageDir} && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` +
+ `rm -rf $out.input.pc_state.new; fi && ` +
+ `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` +
+ `rm -rf $out.deps.pc_state.new; fi && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
+ CommandDeps: []string{
+ "${config.IncrementalDexInputCmd}",
+ "${config.D8Cmd}",
+ "${config.R8Cmd}",
+ "${config.SoongZipCmd}",
+ "${config.MergeZipsCmd}",
+ },
+ }, map[string]*remoteexec.REParams{
+ "$d8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "d8"},
+ Inputs: []string{"${config.D8Jar}"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$r8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "r8"},
+ Inputs: []string{"$implicits", "${config.R8Jar}"},
+ OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
+ "d8Flags", "d8Deps", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -195,6 +322,7 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
`rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar"`,
CommandDeps: []string{
"${config.D8Cmd}",
+ "${config.D8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -250,7 +378,9 @@ var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8",
`rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
CommandDeps: []string{
"${config.D8Cmd}",
+ "${config.D8Jar}",
"${config.R8Cmd}",
+ "${config.R8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -301,6 +431,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
Deps: blueprint.DepsGCC,
CommandDeps: []string{
"${config.R8Cmd}",
+ "${config.R8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -330,8 +461,14 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
"r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+var proguardDictToProto = pctx.AndroidStaticRule("proguard_dict_to_proto", blueprint.RuleParams{
+ Command: `${symbols_map} -r8 $in -location $location -write_if_changed $out`,
+ Restat: true,
+ CommandDeps: []string{"${symbols_map}"},
+}, "location")
+
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
- dexParams *compileDexParams) (flags []string, deps android.Paths) {
+ dexParams *compileDexParams) (flags []string, deps android.Paths, incD8Compatible bool) {
flags = d.dexProperties.Dxflags
// Translate all the DX flags to D8 ones until all the build files have been migrated
@@ -401,36 +538,41 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
}
flags = append(flags, "--min-api "+strconv.Itoa(minApiFlagValue))
+ incD8Compatible = false
+ // Incremental d8 does not have libraries passed to it for speed, so any
+ // desugaring with library classes is not possible.
+ // To cater for this we only enable incD8 when platform build flag is passed
+ // as it automatically disables desugaring.
if addAndroidPlatformBuildFlag {
flags = append(flags, "--android-platform-build")
+ incD8Compatible = true
}
- return flags, deps
+ return flags, deps, incD8Compatible
}
-func (d *dexer) d8Flags(ctx android.ModuleContext, dexParams *compileDexParams) (d8Flags []string, d8Deps android.Paths, artProfileOutput *android.OutputPath) {
+func (d *dexer) d8Flags(ctx android.ModuleContext, dexParams *compileDexParams, useD8Inc bool) (d8Flags []string, d8Deps android.Paths, artProfileOutput *android.OutputPath) {
flags := dexParams.flags
d8Flags = append(d8Flags, flags.bootClasspath.FormRepeatedClassPath("--lib ")...)
d8Flags = append(d8Flags, flags.dexClasspath.FormRepeatedClassPath("--lib ")...)
-
d8Deps = append(d8Deps, flags.bootClasspath...)
d8Deps = append(d8Deps, flags.dexClasspath...)
-
- if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
- d8Flags = append(d8Flags, flags...)
- d8Deps = append(d8Deps, deps...)
- artProfileOutput = profileOutput
+ if !useD8Inc {
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ d8Flags = append(d8Flags, flags...)
+ d8Deps = append(d8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
}
return d8Flags, d8Deps, artProfileOutput
}
-func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, debugMode bool) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
- flags := dexParams.flags
- opt := d.dexProperties.Optimize
+func (d *dexer) r8DepLibFlags(ctx android.ModuleContext, dexParams *compileDexParams) (r8Flags []string, r8Deps android.Paths) {
+ var depLibs classpath
// When an app contains references to APIs that are not in the SDK specified by
// its LOCAL_SDK_VERSION for example added by support library or by runtime
- // classes added by desugaring, we artifically raise the "SDK version" "linked" by
+ // classes added by desugaring, we artificially raise the "SDK version" "linked" by
// ProGuard, to
// - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
@@ -443,14 +585,11 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
}
})
- r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, proguardRaiseDeps...)
+ depLibs = append(depLibs, proguardRaiseDeps...)
}
- r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, flags.bootClasspath...)
- r8Flags = append(r8Flags, flags.dexClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, flags.dexClasspath...)
+ depLibs = append(depLibs, dexParams.flags.bootClasspath...)
+ depLibs = append(depLibs, dexParams.flags.dexClasspath...)
transitiveStaticLibsLookupMap := map[android.Path]bool{}
for _, jar := range d.transitiveStaticLibsHeaderJarsForR8.ToList() {
@@ -465,8 +604,27 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
transitiveHeaderJars = append(transitiveHeaderJars, jar)
}
transitiveClasspath := classpath(transitiveHeaderJars)
- r8Flags = append(r8Flags, transitiveClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, transitiveClasspath...)
+ depLibs = append(depLibs, transitiveClasspath...)
+
+ depLibs = depLibs.FirstUniquePaths()
+ r8Deps = append(r8Deps, depLibs...)
+
+ var libraryDepArg string
+ if Bool(d.dexProperties.Optimize.Import_libraries_as_classpath) {
+ libraryDepArg = "--classpath "
+ } else {
+ libraryDepArg = "--lib "
+ }
+ r8Flags = append(r8Flags, depLibs.FormRepeatedClassPath(libraryDepArg)...)
+
+ return r8Flags, r8Deps
+}
+
+func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, debugMode, useD8Inc bool) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
+ r8Flags, r8Deps = d.r8DepLibFlags(ctx, dexParams)
+
+ flags := dexParams.flags
+ opt := d.dexProperties.Optimize
flagFiles := android.Paths{
android.PathForSource(ctx, "build/make/core/proguard.flags"),
@@ -525,7 +683,8 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
// Avoid unnecessary stack frame noise by only injecting source map ids for non-debug
// optimized or obfuscated targets.
- if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode {
+ optimize := opt.Optimize.GetOrDefault(ctx, false)
+ if (optimize || Bool(opt.Obfuscate)) && !debugMode {
// TODO(b/213833843): Allow configuration of the prefix via a build variable.
var sourceFilePrefix = "go/retraceme "
var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\""
@@ -538,7 +697,7 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
r8Flags = append(r8Flags, "-dontshrink")
}
- if !Bool(opt.Optimize) {
+ if !optimize {
r8Flags = append(r8Flags, "-dontoptimize")
}
@@ -569,10 +728,12 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
}
}
- if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
- r8Flags = append(r8Flags, flags...)
- r8Deps = append(r8Deps, deps...)
- artProfileOutput = profileOutput
+ if !useD8Inc {
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ r8Flags = append(r8Flags, flags...)
+ r8Deps = append(r8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
}
if ctx.Config().UseR8StoreStoreFenceConstructorInlining() {
@@ -623,21 +784,23 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- zipFlags := "--ignore_missing_files"
+ zipFlags := "--ignore_missing_files --quiet"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
- commonFlags, commonDeps := d.dexCommonFlags(ctx, dexParams)
+ commonFlags, commonDeps, incD8Compatible := d.dexCommonFlags(ctx, dexParams)
// Exclude kotlinc generated files when "exclude_kotlinc_generated_files" is set to true.
mergeZipsFlags := ""
if proptools.BoolDefault(d.dexProperties.Exclude_kotlinc_generated_files, false) {
- mergeZipsFlags = "-stripFile META-INF/*.kotlin_module -stripFile **/*.kotlin_builtins"
+ mergeZipsFlags = "-stripFile META-INF/**/*.kotlin_module -stripFile **/*.kotlin_builtins"
}
useR8 := d.effectiveOptimizeEnabled(ctx)
useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8
+ // d8Inc is applicable only when d8 is allowed.
+ useD8Inc := useD8 && ctx.Config().PartialCompileFlags().Enable_inc_d8 && incD8Compatible
rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8")
rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8")
var rule blueprint.Rule
@@ -669,7 +832,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
}...)
description = "r8"
debugMode := android.InList("--debug", commonFlags)
- r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode)
+ r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode, useD8Inc)
deps = append(deps, r8Deps...)
args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ")
if r8ArtProfileOutputPath != nil {
@@ -694,25 +857,61 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
args["implicits"] = strings.Join(deps.Strings(), ",")
}
}
+ cleanupD8R8, cleanupD8IncR8, cleanupD8Inc := false, false, false
if useD8 {
description = "d8"
- d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams)
+ d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams, useD8Inc)
deps = append(deps, d8Deps...)
deps = append(deps, commonDeps...)
args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ")
if d8ArtProfileOutputPath != nil {
artProfileOutputPath = d8ArtProfileOutputPath
}
+ // The file containing dependencies of the current module
+ // Any change in them may warrant changes in the incremental dex compilation
+ // source set.
+ if useD8Inc {
+ d8DepsFile := android.PathForModuleOut(ctx, dexParams.jarName+".dex.deps.rsp")
+ android.WriteFileRule(ctx, d8DepsFile, strings.Join(deps.Strings(), "\n"))
+ deps = append(deps, d8DepsFile)
+ args["d8Deps"] = d8DepsFile.String()
+ }
// If we are generating both d8 and r8, only use RBE when both are enabled.
switch {
+ // r8 is the selected rule, useD8Inc is the override
+ case useR8 && rule == r8 && useD8Inc:
+ rule = d8IncR8
+ cleanupD8IncR8 = true
+ description = "d8IncR8"
+ // r8 is the selected rule, useD8 is the override
case useR8 && rule == r8:
rule = d8r8
+ cleanupD8R8 = true
description = "d8r8"
+ // rbeR8 is the selected rule, useD8Inc is the override
+ case useR8 && rule == r8RE && useD8Inc:
+ rule = d8IncR8RE
+ cleanupD8IncR8 = true
+ description = "d8IncR8"
+ // rbeR8 is the selected rule, useD8 is the override
case useR8 && rule == r8RE && rbeD8:
rule = d8r8RE
+ cleanupD8R8 = true
description = "d8r8"
+ // rbeD8 is the selected rule, useD8Inc is the override
+ case rbeD8 && useD8Inc:
+ rule = d8IncRE
+ cleanupD8Inc = true
+ description = "d8Inc"
+ // rbeD8 is the selected rule
case rbeD8:
rule = d8RE
+ // D8 is the selected rule, useD8Inc is the override
+ case useD8Inc:
+ rule = d8Inc
+ cleanupD8Inc = true
+ description = "d8Inc"
+ // D8 is the selected rule
default:
rule = d8
}
@@ -732,7 +931,8 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
Implicits: deps,
Args: args,
})
- if useR8 && useD8 {
+ // Run cleanup when d8r8 was used
+ if cleanupD8R8 {
// Generate the rule for partial compile clean.
args["builtOut"] = javalibJar.String()
ctx.Build(pctx, android.BuildParams{
@@ -744,6 +944,32 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
})
ctx.Phony("partialcompileclean", cleanPhonyPath)
}
+ // Run cleanup when d8IncR8 was used
+ if cleanupD8IncR8 {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8IncR8Clean,
+ Description: "d8IncR8Clean",
+ Output: cleanPhonyPath,
+ Args: args,
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+ }
+ // Run cleanup when d8Inc was used
+ if cleanupD8Inc {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8IncClean,
+ Description: "d8IncClean",
+ Output: cleanPhonyPath,
+ Args: args,
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+ }
if proptools.Bool(d.dexProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
@@ -754,6 +980,64 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
return javalibJar, artProfileOutputPath
}
+type ProguardZips struct {
+ DictZip android.Path
+ DictMapping android.Path
+ UsageZip android.Path
+}
+
+func BuildProguardZips(ctx android.ModuleContext, modules []android.ModuleOrProxy) ProguardZips {
+ dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip")
+ dictZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip)
+
+ dictMapping := android.PathForModuleOut(ctx, "proguard-dict-mapping.textproto")
+ dictMappingBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictMappingCmd := dictMappingBuilder.Command().BuiltTool("symbols_map").Flag("-merge").Output(dictMapping)
+
+ protosDir := android.PathForModuleOut(ctx, "proguard_mapping_protos")
+
+ usageZip := android.PathForModuleOut(ctx, "proguard-usage.zip")
+ usageZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ usageZipCmd := usageZipBuilder.Command().BuiltTool("merge_zips").Output(usageZip)
+
+ for _, mod := range modules {
+ if proguardInfo, ok := android.OtherModuleProvider(ctx, mod, ProguardProvider); ok {
+ // Maintain these out/target/common paths for backwards compatibility. They may be able
+ // to be changed if tools look up file locations from the protobuf, but I'm not
+ // exactly sure how that works.
+ dictionaryFakePath := fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/proguard_dictionary", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithArg("-e ", dictionaryFakePath)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ProguardDictionary)
+ dictZipCmd.Textf("-e out/target/common/obj/%s/%s_intermediates/classes.jar", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ClassesJar)
+
+ protoFile := protosDir.Join(ctx, filepath.Dir(dictionaryFakePath), "proguard_dictionary.textproto")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: proguardDictToProto,
+ Input: proguardInfo.ProguardDictionary,
+ Output: protoFile,
+ Args: map[string]string{
+ "location": dictionaryFakePath,
+ },
+ })
+ dictMappingCmd.Input(protoFile)
+
+ usageZipCmd.Input(proguardInfo.ProguardUsageZip)
+ }
+ }
+
+ dictZipBuilder.Build("proguard_dict_zip", "Building proguard dictionary zip")
+ dictMappingBuilder.Build("proguard_dict_mapping_proto", "Building proguard mapping proto")
+ usageZipBuilder.Build("proguard_usage_zip", "Building proguard usage zip")
+
+ return ProguardZips{
+ DictZip: dictZip,
+ DictMapping: dictMapping,
+ UsageZip: usageZip,
+ }
+}
+
type ProguardInfo struct {
ModuleName string
Class string
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index e8e1cd405..c42997b92 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -644,7 +644,7 @@ func checkSystemServerOrder(ctx android.ModuleContext, libName string) {
config := dexpreopt.GetGlobalConfig(ctx)
jars := config.AllSystemServerClasspathJars(ctx)
jarIndex := config.AllSystemServerJars(ctx).IndexOfJar(libName)
- ctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(dep android.ModuleProxy, parent android.ModuleProxy) bool {
tag := ctx.OtherModuleDependencyTag(dep)
// Ideally this should only be walking relevant dependencies, but to maintain existing behavior
// for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 228704355..f302915b4 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -540,7 +540,7 @@ func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) {
// This dependency will be used to get the path to the deapexed dex boot jars and profile (via a provider)
func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorContext, apexes ...string) {
psi := android.PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDepsWithTag(apexContributionsMetadataDepTag, func(am android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(apexContributionsMetadataDepTag, func(am android.ModuleProxy) {
if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists {
psi = info
}
@@ -562,9 +562,9 @@ func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorConte
}
}
-func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
+func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.ModuleProxy {
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
- fragments := make(map[string]android.Module)
+ fragments := make(map[string]android.ModuleProxy)
type moduleInApexPair struct {
module string
@@ -574,7 +574,7 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.
var modulesInApexes []moduleInApexPair
// Find the list of modules in apexes.
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
if !isActiveModule(ctx, child) {
return false
}
@@ -596,7 +596,7 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.
for _, moduleInApex := range modulesInApexes {
// Find a desired module in an apex.
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
t := ctx.OtherModuleDependencyTag(child)
if bcpTag, ok := t.(bootclasspathDependencyTag); ok {
if bcpTag.typ == platform {
@@ -615,10 +615,10 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.
}
return fragments
- }).(map[string]android.Module)
+ }).(map[string]android.ModuleProxy)
}
-func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.Module {
+func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.ModuleProxy {
return gatherBootclasspathFragments(ctx)[apexName]
}
@@ -767,6 +767,7 @@ func (d *dexpreoptBootJars) buildBootZip(ctx android.ModuleContext) {
Inputs: []android.Path{
bootZipMetadataTmp,
globalSoong.UffdGcFlag,
+ globalSoong.AssumeValueFlags,
newlineFile,
},
Output: bootZipMetadata,
@@ -863,7 +864,7 @@ func generateBootImage(ctx android.ModuleContext, imageConfig *bootImageConfig)
type apexJarModulePair struct {
apex string
- jarModule android.Module
+ jarModule android.ModuleProxy
}
func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []apexJarModulePair {
@@ -923,9 +924,9 @@ func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.Modu
}
// Returns the stem of an artifact inside a prebuilt apex
-func ModuleStemForDeapexing(m android.Module) string {
- bmn, _ := m.(interface{ BaseModuleName() string })
- return bmn.BaseModuleName()
+func ModuleStemForDeapexing(ctx android.OtherModuleProviderContext, m android.ModuleOrProxy) string {
+ info := android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
+ return info.BaseModuleName
}
// Returns the java libraries exported by the apex for hiddenapi and dexpreopt
@@ -934,11 +935,11 @@ func ModuleStemForDeapexing(m android.Module) string {
// 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path {
- if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, ModuleStemForDeapexing(pair.jarModule)); found {
+ if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, ModuleStemForDeapexing(ctx, pair.jarModule)); found {
return dex
}
// TODO: b/308174306 - Remove the legacy mechanism
- if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
+ if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(ctx, pair.jarModule) {
// This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API
// files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for
// a source APEX because there is no guarantee that it is the same as the jar packed into the
@@ -949,7 +950,7 @@ func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNam
} else {
// Use exactly the same jar that is packed into the APEX.
fragment := getBootclasspathFragmentByApex(ctx, pair.apex)
- if fragment == nil {
+ if fragment.IsNil() {
ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+
"APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
pair.jarModule.Name(),
@@ -1110,20 +1111,25 @@ func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameT
}
// TODO: b/308174306 - Remove the legacy mechanism
fragment := getBootclasspathFragmentByApex(ctx, apexName)
- if fragment == nil {
+ if fragment.IsNil() {
ctx.ModuleErrorf("Boot image config imports profile from '%[2]s', but a "+
"bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
"dependency of dex_bootjars",
apexName)
return nil
}
- return fragment.(commonBootclasspathFragment).getProfilePath()
+
+ if info, ok := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentInfoProvider); ok {
+ return info.ProfilePathOnHost
+ } else {
+ panic(fmt.Errorf("missing BootclasspathFragmentInfoProvider in %s", fragment))
+ }
}
func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
- ctx.VisitDirectDeps(func(am android.Module) {
+ ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(am)
if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
if bcpTag.moduleInApex == "" {
@@ -1323,6 +1329,8 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
cmd.Flag(global.BootFlags)
}
+ cmd.Text("$(cat").Input(globalSoong.AssumeValueFlags).Text(")")
+
if extraFlags != "" {
cmd.Flag(extraFlags)
}
@@ -1381,6 +1389,10 @@ const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
It is likely that the boot classpath is inconsistent.
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
+// bootImageProfileRuleCommon contains the common logic for generating boot image profiles for both
+// the platform and the ART module when building from source.
+// Building from prebuilts is not handled here. Instead, the profile is extracted from the prebuilt
+// ART module.
func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles android.Paths, dexLocations []string) android.WritablePath {
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -1389,33 +1401,35 @@ func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles
return nil
}
- defaultProfile := "frameworks/base/boot/boot-image-profile.txt"
- // If ART is prebuilt, primarily in next release configs, this will still use
- // the profile from source which represent the latest code, so it may not
- // correspond to the BCP jars in the prebuilt APEX, but this is the profile we
- // have access to.
- artProfile := "art/build/boot/boot-image-profile.txt"
- extraProfile := "frameworks/base/boot/boot-image-profile-extra.txt"
-
rule := android.NewRuleBuilder(pctx, ctx)
var profiles android.Paths
if len(global.BootImageProfiles) > 0 {
+ // The most common case. The profiles are specified by
+ // `PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION`.
+ // - On a bundled build, this list contains both the ART profile and the frameworks profile.
+ // - On an unbundled build with ART source code being present, this list only contains the ART
+ // profile.
profiles = append(profiles, global.BootImageProfiles...)
- } else if path := android.ExistentPathForSource(ctx, defaultProfile); path.Valid() {
- profiles = append(profiles, path.Path())
} else {
- // No profile (not even a default one, which is the case on some branches
- // like master-art-host that don't have frameworks/base).
+ // No profile specified. This means we are building an unbundled build with ART source code
+ // being absent, meaning we are not building the platform or the ART module, so we don't need
+ // a profile.
// Return nil and continue without profile.
return nil
}
- if path := android.ExistentPathForSource(ctx, artProfile); path.Valid() {
- profiles = append(profiles, path.Path())
- }
+ extraProfile := "frameworks/base/boot/boot-image-profile-extra.txt"
if path := android.ExistentPathForSource(ctx, extraProfile); path.Valid() {
profiles = append(profiles, path.Path())
}
+
+ // Remove duplicates while preserving order to ensure deterministic builds.
+ profiles = android.FirstUniquePaths(profiles)
+
+ // We concatenate the profiles into a single file. Later, `profman` filters the entries based on
+ // `dexFiles` to only keep the relevant ones. For example, when this function is called for
+ // generating the profile for the ART module, `profman` only keeps the entries for the ART module
+ // and not the platform.
bootImageProfile := android.PathForModuleOut(ctx, name, "boot-image-profile.txt")
rule.Command().Text("cat").Inputs(profiles).Text(">").Output(bootImageProfile)
@@ -1621,7 +1635,7 @@ func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) {
}
func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(m)
if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar {
if bcpTag.moduleInApex != "" {
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
index 9d0f539ba..f7d46144a 100644
--- a/java/dexpreopt_check.go
+++ b/java/dexpreopt_check.go
@@ -95,16 +95,17 @@ func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.Mod
global := dexpreopt.GetGlobalConfig(ctx)
targets := ctx.Config().Targets[android.Android]
- ctx.VisitDirectDepsWithTag(systemServerJarDepTag, func(systemServerJar android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(systemServerJarDepTag, func(systemServerJar android.ModuleProxy) {
partition := "system"
- if systemServerJar.InstallInSystemExt() && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() {
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, systemServerJar, android.CommonModuleInfoProvider)
+ if commonInfo.SystemExtSpecific && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() {
partition = ctx.DeviceConfig().SystemExtPath() // system_ext
}
var dexLocation string
- if m, ok := systemServerJar.(ModuleWithStem); ok {
- dexLocation = dexpreopt.GetSystemServerDexLocation(ctx, global, m.Stem())
+ if javaInfo, ok := android.OtherModuleProvider(ctx, systemServerJar, JavaInfoProvider); ok {
+ dexLocation = dexpreopt.GetSystemServerDexLocation(ctx, global, javaInfo.Stem)
} else {
- ctx.PropertyErrorf("dexpreopt_systemserver_check", "%v is not a ModuleWithStem", systemServerJar.Name())
+ ctx.PropertyErrorf("dexpreopt_systemserver_check", "%v does not have JavaInfo", systemServerJar.Name())
}
odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType, partition)
odexPath := getInstallPath(ctx, odexLocation)
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index f437da02c..775966153 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -402,3 +402,44 @@ func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) {
android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs())
}
+
+func TestAssumeValueFlags(t *testing.T) {
+ for _, platformSdkVersion := range []string{"", "28"} {
+ t.Run(platformSdkVersion, func(t *testing.T) {
+ preparers := android.GroupFixturePreparers(
+ PrepareForTestWithDexpreopt,
+ dexpreopt.PrepareForTestWithDexpreoptConfig,
+ dexpreopt.FixtureSetEnableUffdGc("false"),
+ dexpreopt.FixtureSetPlatformSdkVersion(platformSdkVersion),
+ )
+
+ result := preparers.RunTestWithBp(t, `
+ java_library {
+ name: "foo",
+ installable: true,
+ dex_preopt: {
+ profile: "art-profile",
+ },
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }`)
+
+ ctx := result.TestContext
+
+ // Ensure that we always have a valid (but possibly empty) assumed
+ // value flags file for use with dex2oat input.
+ ctx.SingletonForTests(t, "dexpreopt-soong-config").Output("out/soong/dexpreopt/assume_value_flags.txt")
+
+ // If the SDK version is set, it should exist in the command to
+ // generate the assumed value flags file for use with dex2oat input.
+ if platformSdkVersion != "" {
+ rule := ctx.SingletonForTests(t, "dexpreopt-soong-config").Rule("dexpreopt_assume_value_flags")
+ android.AssertStringDoesContain(t, "", rule.RuleParams.Command,
+ "echo '--assume-value=Landroid/os/Build$$VERSION;->SDK_INT:"+platformSdkVersion+"'")
+ android.AssertStringPathsRelativeToTopEquals(t, "", ctx.Config(), []string{
+ "out/soong/dexpreopt/assume_value_flags.txt",
+ }, rule.AllOutputs())
+ }
+ })
+ }
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 3faf294de..a65427f8b 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -195,9 +195,6 @@ func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersio
"them instead.")
}
return false
- } else if ctx.Config().PartialCompileFlags().Disable_stub_validation &&
- !ctx.Config().BuildFromTextStub() {
- return false
} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
return true
} else if String(apiToCheck.Api_file) != "" {
@@ -432,8 +429,8 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
for _, src := range j.properties.Srcs {
if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" {
otherModule := android.GetModuleProxyFromPathDep(ctx, moduleName, tag)
- if otherModule != nil {
- if dep, ok := android.OtherModuleProvider(ctx, *otherModule, android.CodegenInfoProvider); ok {
+ if !otherModule.IsNil() {
+ if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
}
}
@@ -651,9 +648,9 @@ func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.Rule
ctx.PropertyErrorf("custom_template", "must specify a template")
}
- ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
+ ctx.VisitDirectDepsProxyWithTag(droiddocTemplateTag, func(m android.ModuleProxy) {
+ if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok {
+ cmd.FlagWithArg("-templatedir ", t.Dir.String()).Implicits(t.Deps)
} else {
ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index b30c8448a..c2a5c046e 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -18,6 +18,7 @@ import (
"fmt"
"path/filepath"
"regexp"
+ "slices"
"strings"
"github.com/google/blueprint"
@@ -36,6 +37,7 @@ type StubsInfo struct {
}
type DroidStubsInfo struct {
+ AconfigProtoFiles android.Paths
CurrentApiTimestamp android.Path
EverythingStubsInfo StubsInfo
ExportableStubsInfo StubsInfo
@@ -437,6 +439,8 @@ func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
if d.properties.Api_levels_module != nil {
ctx.AddDependency(ctx.Module(), metalavaAPILevelsModuleTag, proptools.String(d.properties.Api_levels_module))
}
+
+ d.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
func (d *Droidstubs) sdkValuesFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, metadataDir android.WritablePath) {
@@ -593,6 +597,18 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
+ // If generating the android API then include android.test.*.jars in the set
+ // of files passed to Metalava.
+ filenames := []string{filename}
+ if filename == "android.jar" {
+ filenames = append(
+ filenames,
+ "android.test.base.jar",
+ "android.test.mock.jar",
+ "android.test.runner.jar",
+ )
+ }
+
// TODO: Avoid the duplication of API surfaces, reuse apiScope.
// Add all relevant --android-jar-pattern patterns for Metalava.
// When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
@@ -648,7 +664,7 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
extensions_dir = t.Dir.String() + "/extensions"
}
cmd.Implicit(dep)
- } else if depBase == filename {
+ } else if slices.Contains(filenames, depBase) {
// Check to see if it matches a dessert release for an SDK, e.g. Android, Car, Wear, etc..
cmd.Implicit(dep)
} else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
@@ -688,7 +704,16 @@ func (d *Droidstubs) apiLevelsGenerationFlags(ctx android.ModuleContext, cmd *an
addPattern(AndroidPlusUpdatableJar)
}
+ // Always add the main jar, e.g. android.jar. This will be overridden by
+ // android-plus-updatable.jar if a pattern for it was added as that comes
+ // first and neither has a library placeholder.
addPattern(filename)
+
+ // If additional file names were added then they are assumed to be
+ // libraries so match them using a {library} placeholder.
+ if len(filenames) > 1 {
+ addPattern("{library}.jar")
+ }
}
if extensions_dir != "" {
@@ -1251,7 +1276,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Add options for the other optional tasks: API-lint and check-released.
// We generate separate timestamp files for them.
- doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().PartialCompileFlags().Disable_api_lint
+ doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
writeSdkValues := Bool(d.properties.Write_sdk_values)
@@ -1380,15 +1405,12 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if d.apiLintTimestamp != nil {
cmd.Validation(d.apiLintTimestamp)
}
-
if d.checkLastReleasedApiTimestamp != nil {
cmd.Validation(d.checkLastReleasedApiTimestamp)
}
-
if d.checkNullabilityWarningsTimestamp != nil {
cmd.Validation(d.checkNullabilityWarningsTimestamp)
}
-
rule.Build("metalavaCurrentApiCheck", "check current API")
d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp")
@@ -1407,6 +1429,9 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Input(d.removedApiFile).Flag(removedApiFile.String())
msg = "failed to update public API"
+ if ctx.Config().GetBuildFlagBool("RELEASE_SRC_DIR_IS_READ_ONLY") {
+ msg += ". You may need `BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true`"
+ }
rule.Command().
Text("touch").Output(d.updateCurrentApiTimestamp).
@@ -1419,6 +1444,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
droidInfo := DroidStubsInfo{
+ AconfigProtoFiles: deps.aconfigProtoFiles,
CurrentApiTimestamp: d.CurrentApiTimestamp(),
EverythingStubsInfo: StubsInfo{},
ExportableStubsInfo: StubsInfo{},
@@ -1593,6 +1619,10 @@ func (d *PrebuiltStubsSources) StubsSrcJar(_ StubsType) (android.Path, error) {
return d.stubsSrcJar, nil
}
+func (p *PrebuiltStubsSources) DepsMutator(ctx android.BottomUpMutatorContext) {
+ p.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
+}
+
func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(p.properties.Srcs) != 1 {
ctx.PropertyErrorf("srcs", "must only specify one directory path or srcjar, contains %d paths", len(p.properties.Srcs))
diff --git a/java/fuzz.go b/java/fuzz.go
index 0e239f0ec..922585b8d 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -51,6 +51,12 @@ type JavaFuzzTest struct {
jniFilePaths android.Paths
}
+type JavaFuzzTestInfo struct {
+ JniFilePaths android.Paths
+}
+
+var JavaFuzzTestInfoProvider = blueprint.NewProvider[JavaFuzzTestInfo]()
+
// 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)
@@ -131,9 +137,41 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
- j.Test.GenerateAndroidBuildActions(ctx)
+ checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx))
+ j.Test.generateAndroidBuildActionsWithConfig(ctx, nil)
+
+ var compatibilitySupportFiles android.Paths
+ compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile)
+ compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...)
+ compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...)
+ if j.fuzzPackagedModule.Dictionary != nil {
+ compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary)
+ }
+
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: j.testProperties.Test_suites,
+ MainFile: j.outputFile,
+ MainFileStem: j.Stem(),
+ MainFileExt: ".jar",
+ ConfigFile: j.testConfig,
+ ExtraConfigs: j.extraTestConfigs,
+ NeedsArchFolder: ctx.Device(),
+ CompatibilitySupportFiles: compatibilitySupportFiles,
+ PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory),
+ })
+
+ fuzzModuleValidator := fuzz.FuzzModule{
+ j.ModuleBase,
+ j.DefaultableModuleBase,
+ j.ApexModuleBase,
+ }
- fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule)
+ if fuzz.IsValid(ctx, fuzzModuleValidator) {
+ fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule)
+ android.SetProvider(ctx, JavaFuzzTestInfoProvider, JavaFuzzTestInfo{
+ JniFilePaths: j.jniFilePaths,
+ })
+ }
}
type javaFuzzPackager struct {
@@ -149,9 +187,9 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
s.FuzzTargets = make(map[string]bool)
- ctx.VisitAllModules(func(module android.Module) {
+ ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
// Discard non-fuzz targets.
- javaFuzzModule, ok := module.(*JavaFuzzTest)
+ javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider)
if !ok {
return
}
@@ -159,25 +197,21 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
if !ok {
return
}
+ javaFuzzTestInfo, ok := android.OtherModuleProvider(ctx, module, JavaFuzzTestInfoProvider)
+ if !ok {
+ return
+ }
+
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
hostOrTargetString := "target"
- if javaFuzzModule.Target().HostCross {
+ if commonInfo.Target.HostCross {
hostOrTargetString = "host_cross"
- } else if javaFuzzModule.Host() {
+ } else if commonInfo.Host {
hostOrTargetString = "host"
}
- fuzzModuleValidator := fuzz.FuzzModule{
- javaFuzzModule.ModuleBase,
- javaFuzzModule.DefaultableModuleBase,
- javaFuzzModule.ApexModuleBase,
- }
-
- if ok := fuzz.IsValid(ctx, fuzzModuleValidator); !ok {
- return
- }
-
- archString := javaFuzzModule.Arch().ArchType.String()
+ archString := commonInfo.Target.Arch.ArchType.String()
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
@@ -188,14 +222,17 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder)
// Add .jar
- if !javaFuzzModule.Host() {
- files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.implementationJarFile, DestinationPathPrefix: "classes"})
+ if !commonInfo.Host {
+ for _, jar := range javaInfo.ImplementationJars {
+ files = append(files, fuzz.FileToZip{SourceFilePath: jar, DestinationPathPrefix: "classes"})
+ }
}
- files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.outputFile})
+ outputFile := android.OutputFileForModule(ctx, module, "")
+ files = append(files, fuzz.FileToZip{SourceFilePath: outputFile})
// Add jni .so files
- for _, fPath := range javaFuzzModule.jniFilePaths {
+ for _, fPath := range javaFuzzTestInfo.JniFilePaths {
files = append(files, fuzz.FileToZip{SourceFilePath: fPath})
}
@@ -205,6 +242,14 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
}
})
s.CreateFuzzPackage(ctx, archDirs, fuzz.Java, pctx)
+
+ // Create the phony and dist rules
+ ctx.Phony("haiku-java", s.Packages...)
+ ctx.DistForGoals([]string{"haiku-java"}, s.Packages...)
+ for _, target := range android.SortedKeys(s.FuzzTargets) {
+ ctx.Phony("haiku-java", android.PathForPhony(ctx, target))
+ }
+
}
func (s *javaFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
diff --git a/java/genrule_combiner.go b/java/genrule_combiner.go
index 357dc2c76..db6af1ad2 100644
--- a/java/genrule_combiner.go
+++ b/java/genrule_combiner.go
@@ -95,7 +95,7 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext)
// Collect the headers first, so that aconfig flag values for the libraries will override
// values from the headers (if they are different).
- ctx.VisitDirectDepsWithTag(genruleCombinerHeaderDepTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(genruleCombinerHeaderDepTag, func(m android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
j.headerJars = append(j.headerJars, dep.HeaderJars...)
@@ -113,7 +113,7 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext)
ctx.PropertyErrorf("headers", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
}
})
- ctx.VisitDirectDepsWithTag(staticLibTag, func(m android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(m android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
j.implementationJars = append(j.implementationJars, dep.ImplementationJars...)
j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
@@ -178,6 +178,12 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext)
ctx.SetOutputFiles(javaInfo.HeaderJars, ".hjar")
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.combinedImplementationJar != nil {
+ moduleInfoJSON.ClassesJar = []string{j.combinedImplementationJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (j *GenruleCombiner) GeneratedSourceFiles() android.Paths {
@@ -220,10 +226,6 @@ func (j *GenruleCombiner) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
return nil
}
-func (j *GenruleCombiner) JacocoReportClassesFile() android.Path {
- return nil
-}
-
func (j *GenruleCombiner) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index c9a1f2bbe..fe2521cca 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -44,8 +44,7 @@ type hiddenAPI struct {
//
// This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
- bootDexJarPath OptionalDexJarPath
- bootDexJarPathErr error
+ bootDexJarPath OptionalDexJarPath
// The paths to the classes jars that contain classes and class members annotated with
// the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
@@ -57,10 +56,7 @@ type hiddenAPI struct {
uncompressDexState *bool
}
-func (h *hiddenAPI) bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath {
- if h.bootDexJarPathErr != nil {
- ctx.ModuleErrorf(h.bootDexJarPathErr.Error())
- }
+func (h *hiddenAPI) bootDexJar() OptionalDexJarPath {
return h.bootDexJarPath
}
@@ -81,7 +77,7 @@ type hiddenAPIModule interface {
}
type hiddenAPIIntf interface {
- bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath
+ bootDexJar() OptionalDexJarPath
classesJars() android.Paths
uncompressDex() *bool
}
@@ -131,11 +127,6 @@ func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJ
h.active = isModuleInBootClassPath(ctx, module)
}
-// Store any error encountered during the initialization of hiddenapi structure (e.g. unflagged co-existing prebuilt apexes)
-func (h *hiddenAPI) initHiddenAPIError(err error) {
- h.bootDexJarPathErr = err
-}
-
func isModuleInBootClassPath(ctx android.BaseModuleContext, module android.Module) bool {
// Get the configured platform and apex boot jars.
nonApexBootJars := ctx.Config().NonApexBootJars()
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 365005835..d7272433c 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -197,7 +197,7 @@ func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool {
return false
}
-func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+func (b hiddenAPIStubsDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType {
// Do not add additional dependencies to the sdk.
if b.fromAdditionalDependency {
return nil
@@ -205,7 +205,7 @@ func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android
// If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs
// property, otherwise treat if it was specified in the java_header_libs property.
- if javaSdkLibrarySdkMemberType.IsInstance(child) {
+ if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) {
return javaSdkLibrarySdkMemberType
}
@@ -296,7 +296,7 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop
// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
// available, or reports an error.
-func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
+func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.ModuleProxy, kind android.SdkKind) android.Path {
var dexJar OptionalDexJarPath
if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok {
if ctx.Config().ReleaseHiddenApiExportableStubs() {
@@ -304,8 +304,8 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.
} else {
dexJar = sdkLibrary.EverythingStubDexJarPaths[kind]
}
- } else if j, ok := module.(UsesLibraryDependency); ok {
- dexJar = j.DexJarBuildPath(ctx)
+ } else if j, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok && j.UsesLibraryDependencyInfo != nil {
+ dexJar = j.DexJarBuildPath
} else {
ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
return nil
@@ -586,7 +586,7 @@ func newHiddenAPIInfo() *HiddenAPIInfo {
return &info
}
-func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.Module) {
+func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.ModuleProxy) {
// Merge all the information from the fragments. The fragments form a DAG so it is possible that
// this will introduce duplicates so they will be resolved after processing all the fragments.
for _, fragment := range fragments {
@@ -656,7 +656,7 @@ func (s ModuleStubDexJars) stubDexJarForWidestAPIScope() android.Path {
type StubDexJarsByModule map[string]ModuleStubDexJars
// addStubDexJar adds a stub dex jar path provided by the specified module for the specified scope.
-func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.Module, scope *HiddenAPIScope, stubDexJar android.Path) {
+func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.ModuleProxy, scope *HiddenAPIScope, stubDexJar android.Path) {
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
// Each named module provides one dex jar for each scope. However, in some cases different API
@@ -685,13 +685,14 @@ func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module and
// conscrypt.module.public.api java_sdk_library which will be the case once the former has been
// migrated to a module_lib API.
name = "conscrypt.module.public.api"
- } else if d, ok := module.(SdkLibraryComponentDependency); ok {
- sdkLibraryName := d.SdkLibraryName()
- if sdkLibraryName != nil {
- // The module is a component of a java_sdk_library so use the name of the java_sdk_library.
- // e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then
- // use `foo` as the name.
- name = *sdkLibraryName
+ } else {
+ if slcDepInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryComponentDependencyInfoProvider); ok {
+ if sdkLibraryName := slcDepInfo.SdkLibraryName; sdkLibraryName != nil {
+ // The module is a component of a java_sdk_library so use the name of the java_sdk_library.
+ // e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then
+ // use `foo` as the name.
+ name = *sdkLibraryName
+ }
}
}
stubDexJarsByScope := s[name]
@@ -785,7 +786,7 @@ func (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPa
i.SplitPackages = p.Hidden_api.Split_packages
}
-func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) {
+func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.ModuleProxy) {
for _, module := range contents {
if info, ok := android.OtherModuleProvider(ctx, module, hiddenAPIPropertyInfoProvider); ok {
i.FlagFilesByCategory.append(info.FlagFilesByCategory)
@@ -844,8 +845,8 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput {
// dependencies added in hiddenAPIAddStubLibDependencies.
//
// That includes paths to the stub dex jars as well as paths to the *removed.txt files.
-func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.Module) {
- addFromModule := func(ctx android.ModuleContext, module android.Module, apiScope *HiddenAPIScope) {
+func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.ModuleProxy) {
+ addFromModule := func(ctx android.ModuleContext, module android.ModuleProxy, apiScope *HiddenAPIScope) {
sdkKind := apiScope.sdkKind
dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, sdkKind)
if dexJar != nil {
@@ -868,7 +869,7 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten
}
}
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(module)
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
apiScope := hiddenAPIStubsTag.apiScope
@@ -927,7 +928,7 @@ type HiddenAPIFlagOutput struct {
type bootDexJarByModule map[string]android.Path
// addPath adds the path for a module to the map.
-func (b bootDexJarByModule) addPath(module android.Module, path android.Path) {
+func (b bootDexJarByModule) addPath(module android.ModuleProxy, path android.Path) {
b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path
}
@@ -1168,7 +1169,7 @@ func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name strin
// * metadata.csv
// * index.csv
// * all-flags.csv
-func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput {
+func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.ModuleProxy, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput {
hiddenApiSubDir := "modular-hiddenapi" + suffix
// Generate the stub-flags.csv.
@@ -1176,7 +1177,7 @@ func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootD
buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil)
// Extract the classes jars from the contents.
- classesJars := extractClassesJarsFromModules(contents)
+ classesJars := extractClassesJarsFromModules(ctx, contents)
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
@@ -1266,7 +1267,7 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s
// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo
// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
-func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
+func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) bootDexJarByModule {
bootDexJars := bootDexJarByModule{}
apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
@@ -1283,28 +1284,12 @@ func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android
if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists {
continue
}
- hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
- if hiddenAPIModule == nil {
- continue
- }
- bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
+ bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, module)
bootDexJars.addPath(module, bootDexJar)
}
return bootDexJars
}
-func hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Module) hiddenAPIModule {
- if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
- return hiddenAPIModule
- } else if _, ok := module.(*DexImport); ok {
- // Ignore this for the purposes of hidden API processing
- } else {
- ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
- }
-
- return nil
-}
-
// bootDexInfo encapsulates both the path and uncompressDex status retrieved from a hiddenAPIModule.
type bootDexInfo struct {
// The path to the dex jar that has not had hidden API flags encoded into it.
@@ -1332,15 +1317,16 @@ func (b bootDexInfoByModule) bootDexJars() android.Paths {
// extractBootDexInfoFromModules extracts the boot dex jar and uncompress dex state from
// each of the supplied modules which must implement hiddenAPIModule.
-func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.Module) bootDexInfoByModule {
+func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) bootDexInfoByModule {
bootDexJarsByModule := bootDexInfoByModule{}
for _, module := range contents {
- hiddenAPIModule := module.(hiddenAPIModule)
- bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
+ bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, module)
+ info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider)
+ commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
bootDexJarsByModule[module.Name()] = bootDexInfo{
path: bootDexJar,
- uncompressDex: *hiddenAPIModule.uncompressDex(),
- minSdkVersion: hiddenAPIModule.MinSdkVersion(ctx),
+ uncompressDex: Bool(info.UncompressDexState),
+ minSdkVersion: *commonInfo.MinSdkVersion.ApiLevel,
}
}
@@ -1352,37 +1338,31 @@ func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or
// invalid, then create a fake path and either report an error immediately or defer reporting of the
// error until the path is actually used.
-func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
- bootDexJar := module.bootDexJar(ctx)
- if !bootDexJar.Valid() {
+func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module android.ModuleProxy) android.Path {
+ info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider)
+ if !info.BootDexJarPath.Valid() {
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
- handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
+ handleMissingDexBootFile(ctx, module, fake, info.BootDexJarPath.InvalidReason())
return fake
}
- return bootDexJar.Path()
+
+ return info.BootDexJarPath.Path()
}
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
-func extractClassesJarsFromModules(contents []android.Module) android.Paths {
+func extractClassesJarsFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) android.Paths {
classesJars := android.Paths{}
for _, module := range contents {
- classesJars = append(classesJars, retrieveClassesJarsFromModule(module)...)
+ if info, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ classesJars = append(classesJars, info.HiddenapiClassesJarPaths...)
+ }
}
return classesJars
}
-// retrieveClassesJarsFromModule retrieves the classes jars from the supplied module.
-func retrieveClassesJarsFromModule(module android.Module) android.Paths {
- if hiddenAPIModule, ok := module.(hiddenAPIModule); ok {
- return hiddenAPIModule.classesJars()
- }
-
- return nil
-}
-
// deferReportingMissingBootDexJar returns true if a missing boot dex jar should not be reported by
// Soong but should instead only be reported in ninja if the file is actually built.
-func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.Module) bool {
+func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.ModuleOrProxy) bool {
// Any missing dependency should be allowed.
if ctx.Config().AllowMissingDependencies() {
return true
@@ -1423,7 +1403,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
// a prebuilt modules that has other variants which are part of an APEX.
//
// TODO(b/187910671): Remove this once platform variants are no longer created unnecessarily.
- if android.IsModulePrebuilt(module) {
+ if android.IsModulePrebuilt(ctx, module) {
// An inactive source module can still contribute to the APEX but an inactive prebuilt module
// should not contribute to anything. So, rather than have a missing dex jar cause a Soong
// failure defer the error reporting to Ninja. Unless the prebuilt build target is explicitly
@@ -1445,7 +1425,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
// handleMissingDexBootFile will either log a warning or create an error rule to create the fake
// file depending on the value returned from deferReportingMissingBootDexJar.
-func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) {
+func handleMissingDexBootFile(ctx android.ModuleContext, module android.ModuleOrProxy, fake android.WritablePath, reason string) {
if deferReportingMissingBootDexJar(ctx, module) {
// Create an error rule that pretends to create the output file but will actually fail if it
// is run.
@@ -1467,14 +1447,12 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module,
// The returned path will usually be to a dex jar file that has been encoded with hidden API flags.
// However, under certain conditions, e.g. errors, or special build configurations it will return
// a path to a fake file.
-func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path {
- bootDexJar := module.(interface {
- DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath
- }).DexJarBuildPath(ctx)
- if !bootDexJar.Valid() {
+func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.ModuleProxy) android.Path {
+ info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider)
+ if !info.DexJarBuildPath.Valid() {
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name()))
- handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason())
+ handleMissingDexBootFile(ctx, module, fake, info.DexJarBuildPath.InvalidReason())
return fake
}
- return bootDexJar.Path()
+ return info.DexJarBuildPath.Path()
}
diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go
index 1e30c5f82..52e444c6e 100644
--- a/java/hiddenapi_monolithic.go
+++ b/java/hiddenapi_monolithic.go
@@ -62,8 +62,9 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F
for _, element := range classpathElements {
switch e := element.(type) {
case *ClasspathLibraryElement:
- classesJars := retrieveClassesJarsFromModule(e.Module())
- monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...)
+ if info, ok := android.OtherModuleProvider(ctx, e.Module(), JavaInfoProvider); ok {
+ monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, info.HiddenapiClassesJarPaths...)
+ }
case *ClasspathFragmentElement:
fragment := e.Module()
@@ -79,7 +80,7 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F
}
// append appends all the files from the supplied info to the corresponding files in this struct.
-func (i *MonolithicHiddenAPIInfo) append(ctx android.ModuleContext, otherModule android.Module, other *HiddenAPIInfo) {
+func (i *MonolithicHiddenAPIInfo) append(ctx android.ModuleContext, otherModule android.ModuleOrProxy, other *HiddenAPIInfo) {
i.FlagsFilesByCategory.append(other.FlagFilesByCategory)
i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath)
diff --git a/java/jacoco.go b/java/jacoco.go
index 696a0cc37..7a80314c1 100644
--- a/java/jacoco.go
+++ b/java/jacoco.go
@@ -19,6 +19,7 @@ package java
import (
"fmt"
"path/filepath"
+ "slices"
"strings"
"github.com/google/blueprint"
@@ -28,6 +29,10 @@ import (
"android/soong/java/config"
)
+func init() {
+ android.InitRegistrationContext.RegisterParallelSingletonType("device_tests_jacoco_zip", deviceTestsJacocoZipSingletonFactory)
+}
+
var (
jacoco = pctx.AndroidStaticRule("jacoco", blueprint.RuleParams{
Command: `rm -rf $tmpDir && mkdir -p $tmpDir && ` +
@@ -167,3 +172,62 @@ func jacocoFilterToSpec(filter string) (string, error) {
return spec, nil
}
+
+type JacocoInfo struct {
+ ReportClassesFile android.Path
+ Class string
+ ModuleName string
+}
+
+var ApexJacocoInfoProvider = blueprint.NewProvider[[]JacocoInfo]()
+
+type BuildJacocoZipContext interface {
+ android.BuilderContext
+ android.OtherModuleProviderContext
+}
+
+func BuildJacocoZip(ctx BuildJacocoZipContext, modules []android.ModuleOrProxy, outputFile android.WritablePath) {
+ jacocoZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ jacocoZipCmd := jacocoZipBuilder.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", outputFile).
+ Flag("-L 0")
+ for _, m := range modules {
+ if javaInfo, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok && javaInfo.JacocoInfo.ReportClassesFile != nil {
+ jacoco := javaInfo.JacocoInfo
+ jacocoZipCmd.FlagWithArg("-e ", fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/jacoco-report-classes.jar", jacoco.Class, jacoco.ModuleName)).
+ FlagWithInput("-f ", jacoco.ReportClassesFile)
+ } else if info, ok := android.OtherModuleProvider(ctx, m, ApexJacocoInfoProvider); ok {
+ for _, jacoco := range info {
+ jacocoZipCmd.FlagWithArg("-e ", fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/jacoco-report-classes.jar", jacoco.Class, jacoco.ModuleName)).
+ FlagWithInput("-f ", jacoco.ReportClassesFile)
+ }
+ }
+ }
+
+ jacocoZipBuilder.Build("jacoco_report_classes_zip", "Building jacoco report zip")
+}
+
+func deviceTestsJacocoZipSingletonFactory() android.Singleton {
+ return &deviceTestsJacocoZipSingleton{}
+}
+
+type deviceTestsJacocoZipSingleton struct{}
+
+// GenerateBuildActions implements android.Singleton.
+func (d *deviceTestsJacocoZipSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var deviceTestModules []android.ModuleOrProxy
+ ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+ if tsm, ok := android.OtherModuleProvider(ctx, m, android.TestSuiteInfoProvider); ok {
+ if slices.Contains(tsm.TestSuites, "device-tests") {
+ deviceTestModules = append(deviceTestModules, m)
+ }
+ }
+ })
+
+ jacocoZip := DeviceTestsJacocoReportZip(ctx)
+ BuildJacocoZip(ctx, deviceTestModules, jacocoZip)
+}
+
+func DeviceTestsJacocoReportZip(ctx android.PathContext) android.WritablePath {
+ return android.PathForOutput(ctx, "device_tests_jacoco_report_classes_all.jar")
+}
diff --git a/java/java.go b/java/java.go
index 7032078eb..e6315ec77 100644
--- a/java/java.go
+++ b/java/java.go
@@ -38,6 +38,8 @@ import (
"android/soong/tradefed"
)
+//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go
+
func init() {
registerJavaBuildComponents(android.InitRegistrationContext)
@@ -103,8 +105,8 @@ var (
PropertyName: "java_header_libs",
SupportsSdk: true,
},
- func(_ android.SdkMemberContext, j *Library) android.Path {
- headerJars := j.HeaderJars()
+ func(_ android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path {
+ headerJars := javaInfo.HeaderJars
if len(headerJars) != 1 {
panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
}
@@ -116,8 +118,8 @@ var (
}
// Export implementation classes jar as part of the sdk.
- exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path {
- implementationJars := j.ImplementationAndResourcesJars()
+ exportImplementationClassesJar = func(_ android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path {
+ implementationJars := javaInfo.ImplementationAndResourcesJars
if len(implementationJars) != 1 {
panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
}
@@ -160,9 +162,9 @@ var (
PropertyName: "java_boot_libs",
SupportsSdk: true,
},
- func(ctx android.SdkMemberContext, j *Library) android.Path {
+ func(ctx android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path {
if snapshotRequiresImplementationJar(ctx) {
- return exportImplementationClassesJar(ctx, j)
+ return exportImplementationClassesJar(ctx, j, javaInfo)
}
// Java boot libs are only provided in the SDK to provide access to their dex implementation
@@ -202,7 +204,7 @@ var (
// This was only added in Tiramisu.
SupportedBuildReleaseSpecification: "Tiramisu+",
},
- func(ctx android.SdkMemberContext, j *Library) android.Path {
+ func(ctx android.SdkMemberContext, _ android.ModuleProxy, _ *JavaInfo) android.Path {
// Java systemserver libs are only provided in the SDK to provide access to their dex
// implementation jar for use by dexpreopting. They do not need to provide an actual
// implementation jar but the java_import will need a file that exists so just copy an empty
@@ -234,6 +236,7 @@ var (
}, "jar_name", "partition", "main_class")
)
+// @auto-generate: gob
type ProguardSpecInfo struct {
// If true, proguard flags files will be exported to reverse dependencies across libs edges
// If false, proguard flags files will only be exported to reverse dependencies across
@@ -263,11 +266,6 @@ type UsesLibraryDependencyInfo struct {
ClassLoaderContexts dexpreopt.ClassLoaderContextMap
}
-type SdkLibraryComponentDependencyInfo struct {
- // The name of the implementation library for the optional SDK library or nil, if there isn't one.
- OptionalSdkLibraryImplementation *string
-}
-
type ProvidesUsesLibInfo struct {
ProvidesUsesLib *string
}
@@ -281,6 +279,14 @@ type ModuleWithSdkDepInfo struct {
Stubs bool
}
+type ApexDependencyInfo struct {
+ // These fields can be different from the ones in JavaInfo, for example, for sdk_library
+ // the following fields are set since sdk_library inherits the implementations of
+ // ApexDependency from base, but the same-named fields are not set in JavaInfo.
+ HeaderJars android.Paths
+ ImplementationAndResourcesJars android.Paths
+}
+
// JavaInfo contains information about a java module for use by modules that depend on it.
type JavaInfo struct {
// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -290,6 +296,11 @@ type JavaInfo struct {
RepackagedHeaderJars android.Paths
+ // list of header jars that have not been jarjared. This should only be used as part of
+ // handling header_jar_override, where we need to use this as the header jars for this implementation of
+ // The only place this is needed is when `header_jar_override` on another module references this module.
+ LocalHeaderJarsPreJarjar android.Paths
+
// set of header jars for all transitive libs deps
TransitiveLibsHeaderJarsForR8 depset.DepSet[android.Path]
@@ -319,6 +330,9 @@ type JavaInfo struct {
// LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies.
LocalHeaderJars android.Paths
+ // KotlinHeaderJars is a jar that only contains Kotlin classes from this module, but not from any static dependencies.
+ KotlinHeaderJars android.Paths
+
// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
// depending on this module.
AidlIncludeDirs android.Paths
@@ -345,9 +359,9 @@ type JavaInfo struct {
// requiring disbling turbine for any modules that depend on it.
ExportedPluginDisableTurbine bool
- // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
+ // JacocoInfo contains the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
- JacocoReportClassesFile android.Path
+ JacocoInfo JacocoInfo
// StubsLinkType provides information about whether the provided jars are stub jars or
// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
@@ -369,8 +383,6 @@ type JavaInfo struct {
UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
- SdkLibraryComponentDependencyInfo *SdkLibraryComponentDependencyInfo
-
ProvidesUsesLibInfo *ProvidesUsesLibInfo
MissingOptionalUsesLibs []string
@@ -392,6 +404,11 @@ type JavaInfo struct {
// this file so using the encoded dex jar here would result in a cycle in the ninja rules.
BootDexJarPath OptionalDexJarPath
+ // The paths to the classes jars that contain classes and class members annotated with
+ // the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API
+ // processing.
+ HiddenapiClassesJarPaths android.Paths
+
// The compressed state of the dex file being encoded. This is used to ensure that the encoded
// dex file has the same state.
UncompressDexState *bool
@@ -433,8 +450,15 @@ type JavaInfo struct {
DexpreopterInfo *DexpreopterInfo
- XrefJavaFiles android.Paths
- XrefKotlinFiles android.Paths
+ XrefJavaFiles android.Paths
+ XrefKotlinFiles android.Paths
+ OverrideMinSdkVersion *string
+ CompileDex *bool
+ SystemModules string
+ Installable bool
+ ApexDependencyInfo *ApexDependencyInfo
+
+ MaxSdkVersion android.ApiLevel
}
var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
@@ -453,7 +477,8 @@ type DexpreopterInfo struct {
}
type JavaLibraryInfo struct {
- Prebuilt bool
+ Prebuilt bool
+ PermittedPackages []string
}
var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]()
@@ -558,37 +583,59 @@ func IsJniDepTag(depTag blueprint.DependencyTag) bool {
return depTag == jniLibTag || depTag == jniInstallTag
}
+func IsOptionalUsesLibraryDepTag(depTag blueprint.DependencyTag) bool {
+ if tag, ok := depTag.(usesLibraryDependencyTag); ok {
+ return tag.optional
+ }
+ return depTag == r8LibraryJarTag
+}
+
+// A tag that is used for staging the dependencies of a module, for populating uses libraries
+// dependencies.
+type usesLibStagingTagStruct struct {
+ blueprint.BaseDependencyTag
+}
+
+// Mark this tag so dependencies that use it are excluded from APEX contents.
+func (t usesLibStagingTagStruct) ExcludeFromApexContents() {}
+
+var _ android.ExcludeFromApexContentsTag = (*usesLibStagingTagStruct)(nil)
+
var (
- dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
- dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
- staticLibTag = dependencyTag{name: "staticlib", static: true}
- 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}
- exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true}
- bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true}
- systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true}
- frameworkResTag = dependencyTag{name: "framework-res"}
- lineageResTag = dependencyTag{name: "org.lineageos.platform-res"}
- kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true}
- proguardRaiseTag = dependencyTag{name: "proguard-raise"}
- certificateTag = dependencyTag{name: "certificate"}
- instrumentationForTag = dependencyTag{name: "instrumentation_for"}
- extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true}
- jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
- r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
- traceReferencesTag = dependencyTag{name: "trace-references"}
- syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
- javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
- aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
- jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
- usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
- usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
- usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
- usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false)
- usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true)
+ dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
+ dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
+ staticLibTag = dependencyTag{name: "staticlib", static: true}
+ 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}
+ exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true}
+ bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true}
+ systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true}
+ frameworkResTag = dependencyTag{name: "framework-res"}
+ lineageResTag = dependencyTag{name: "org.lineageos.platform-res"}
+ kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true}
+ composeEmbeddablePluginTag = dependencyTag{name: "compose-embeddable-plugin", toolchain: true}
+ composePluginTag = dependencyTag{name: "compose-plugin", toolchain: true}
+ proguardRaiseTag = dependencyTag{name: "proguard-raise"}
+ certificateTag = dependencyTag{name: "certificate"}
+ headerJarOverrideTag = dependencyTag{name: "header-jar-override"}
+ instrumentationForTag = dependencyTag{name: "instrumentation_for"}
+ extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true}
+ jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
+ r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
+ traceReferencesTag = dependencyTag{name: "trace-references"}
+ syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
+ javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
+ aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"}
+ jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true}
+ usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
+ usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
+ usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
+ usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false)
+ usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true)
+ usesLibStagingTag = usesLibStagingTagStruct{}
)
// A list of tags for deps used for compiling a module.
@@ -607,6 +654,8 @@ var (
bootClasspathTag,
systemModulesTag,
java9LibTag,
+ composePluginTag,
+ composeEmbeddablePluginTag,
kotlinPluginTag,
syspropPublicStubDepTag,
instrumentationForTag,
@@ -721,9 +770,14 @@ type deps struct {
srcJars android.Paths
systemModules *systemModules
aidlPreprocess android.OptionalPath
+ composeEmbeddablePlugin android.OptionalPath
+ composePlugin android.OptionalPath
kotlinPlugins android.Paths
aconfigProtoFiles android.Paths
+ headerJarOverride android.OptionalPath
+ headerJarOverridePreJarjar android.OptionalPath
+
disableTurbine bool
transitiveStaticLibsHeaderJars []depset.DepSet[android.Path]
@@ -1152,7 +1206,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
})
android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
- Prebuilt: false,
+ Prebuilt: false,
+ PermittedPackages: j.properties.Permitted_packages,
})
if javaInfo != nil {
@@ -1160,8 +1215,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
javaInfo.ExtraOutputFiles = j.extraOutputFiles
javaInfo.DexJarFile = j.dexJarFile
javaInfo.InstallFile = j.installFile
- javaInfo.BootDexJarPath = j.bootDexJarPath
- javaInfo.UncompressDexState = j.uncompressDexState
javaInfo.Active = j.active
javaInfo.BuiltInstalled = j.builtInstalled
javaInfo.ConfigPath = j.configPath
@@ -1186,7 +1239,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if j.dexer.proguardDictionary.Valid() {
android.SetProvider(ctx, ProguardProvider, ProguardInfo{
- ModuleName: ctx.ModuleName(),
+ ModuleName: android.ModuleNameWithPossibleOverride(ctx),
Class: "JAVA_LIBRARIES",
ProguardDictionary: j.dexer.proguardDictionary.Path(),
ProguardUsageZip: j.dexer.proguardUsageZip.Path(),
@@ -1232,7 +1285,7 @@ func buildComplianceMetadata(ctx android.ModuleContext) {
// Static deps
staticDepNames := make([]string, 0)
staticDepFiles := android.Paths{}
- ctx.VisitDirectDepsWithTag(staticLibTag, func(module android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(module android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
staticDepNames = append(staticDepNames, module.Name())
staticDepFiles = append(staticDepFiles, dep.ImplementationJars...)
@@ -1286,6 +1339,9 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
j.usesLibrary.deps(ctx, false)
j.deps(ctx)
+ if j.properties.Header_jar_override != "" {
+ ctx.AddVariationDependencies(nil, headerJarOverrideTag, j.properties.Header_jar_override)
+ }
if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") {
if dexpreopt.IsDex2oatNeeded(ctx) {
dexpreopt.RegisterToolDeps(ctx)
@@ -1340,7 +1396,7 @@ type librarySdkMemberType struct {
// Function to retrieve the appropriate output jar (implementation or header) from
// the library.
- jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
+ jarToExportGetter func(ctx android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path
// Function to compute the snapshot relative path to which the named library's
// jar should be copied.
@@ -1360,9 +1416,9 @@ func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*Library)
- return ok
+func (mt *librarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ info, ok := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
+ return ok && !info.Prebuilt
}
func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
@@ -1389,26 +1445,30 @@ type librarySdkMemberProperties struct {
DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
}
-func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- j := variant.(*Library)
+func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ //j := variant.(*Library)
+ mctx := ctx.SdkModuleContext()
+ commonInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, android.CommonModuleInfoProvider)
+ javaInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, JavaInfoProvider)
+ libraryInfo := android.OtherModuleProviderOrDefault(mctx, variant, JavaLibraryInfoProvider)
- p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
+ p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, variant, javaInfo)
- p.AidlIncludeDirs = j.AidlIncludeDirs()
+ p.AidlIncludeDirs = javaInfo.AidlIncludeDirs
- p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()
+ p.PermittedPackages = libraryInfo.PermittedPackages
// If the min_sdk_version was set then add the canonical representation of the API level to the
// snapshot.
- if j.overridableProperties.Min_sdk_version != nil {
- canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
+ if javaInfo.OverrideMinSdkVersion != nil {
+ canonical, err := android.ReplaceFinalizedCodenames(mctx.Config(), commonInfo.MinSdkVersion.ApiLevel.String())
if err != nil {
ctx.ModuleErrorf("%s", err)
}
p.MinSdkVersion = proptools.StringPtr(canonical)
}
- if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
+ if javaInfo.ProfileGuided {
p.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
}
@@ -1660,6 +1720,12 @@ type JavaTestImport struct {
dexJarFile android.Path
}
+type JavaTestInfo struct {
+ TestConfig android.Path
+}
+
+var JavaTestInfoProvider = blueprint.NewProvider[JavaTestInfo]()
+
func (j *Test) InstallInTestcases() bool {
// Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into
// testcases by base_rules.mk.
@@ -1815,6 +1881,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
+ j.Test.javaTestSetTestsuiteInfo(ctx)
android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
TestcaseRelDataFiles: testcaseRel(j.data),
OutputFile: j.outputFile,
@@ -1837,6 +1904,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx))
j.generateAndroidBuildActionsWithConfig(ctx, nil)
+ j.javaTestSetTestsuiteInfo(ctx)
}
func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) {
@@ -1942,29 +2010,29 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext,
}
}
moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...)
+}
+func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) {
// Install test deps
- if !ctx.Config().KatiEnabled() {
- pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName())
- if j.testConfig != nil {
- ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig)
- }
- dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml")
- if dynamicConfig.Valid() {
- ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path())
- }
- testDeps := append(j.data, j.extraTestConfigs...)
- for _, data := range android.SortedUniquePaths(testDeps) {
- dataPath := android.DataPath{SrcPath: data}
- ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath})
- }
- if j.outputFile != nil {
- ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
- }
+ var testData []android.DataPath
+ for _, data := range j.data {
+ dataPath := android.DataPath{SrcPath: data}
+ testData = append(testData, dataPath)
}
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: j.testProperties.Test_suites,
+ MainFile: j.outputFile,
+ MainFileStem: j.Stem(),
+ MainFileExt: ".jar",
+ ConfigFile: j.testConfig,
+ ExtraConfigs: j.extraTestConfigs,
+ NeedsArchFolder: ctx.Device(),
+ NonArchData: testData,
+ PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory),
+ })
- android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
- TestSuites: j.testProperties.Test_suites,
+ android.SetProvider(ctx, JavaTestInfoProvider, JavaTestInfo{
+ TestConfig: j.testConfig,
})
}
@@ -1979,12 +2047,20 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex
moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
}
optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml")
+ var config android.Path
if optionalConfig.Valid() {
+ config = optionalConfig.Path()
moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
}
- android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
- TestSuites: j.testHelperLibraryProperties.Test_suites,
+ ctx.SetTestSuiteInfo(android.TestSuiteInfo{
+ TestSuites: j.testHelperLibraryProperties.Test_suites,
+ MainFile: j.outputFile,
+ MainFileStem: j.Stem(),
+ MainFileExt: ".jar",
+ ConfigFile: config,
+ NeedsArchFolder: ctx.Device(),
+ PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory),
})
}
@@ -2008,8 +2084,8 @@ func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, d
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*Test)
+func (mt *testSdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ _, ok := android.OtherModuleProvider(ctx, module, JavaTestInfoProvider)
return ok
}
@@ -2028,16 +2104,14 @@ type testSdkMemberProperties struct {
TestConfig android.Path
}
-func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- test := variant.(*Test)
-
- implementationJars := test.ImplementationJars()
+func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ implementationJars := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, JavaInfoProvider).ImplementationJars
if len(implementationJars) != 1 {
- panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
+ panic(fmt.Errorf("there must be only one implementation jar from %q", variant.Name()))
}
p.JarToExport = implementationJars[0]
- p.TestConfig = test.testConfig
+ p.TestConfig = android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, JavaTestInfoProvider).TestConfig
}
func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -2358,6 +2432,10 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon
})
}
+func (ap *JavaApiContribution) DepsMutator(ctx android.BottomUpMutatorContext) {
+ ap.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
+}
+
type ApiLibrary struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -2546,7 +2624,6 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
apiContributions := al.properties.Api_contributions
addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") &&
!ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") &&
- !ctx.Config().PartialCompileFlags().Disable_stub_validation &&
proptools.BoolDefault(al.properties.Enable_validation, true)
for _, apiContributionName := range apiContributions {
ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)
@@ -2584,6 +2661,8 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName)
}
+
+ al.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
// Map where key is the api scope name and value is the int value
@@ -2722,7 +2801,15 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
}
- al.addValidation(ctx, cmd, al.validationPaths)
+ // While we could use SOONG_USE_PARTIAL_COMPILE in the validation's rule, that would unduly
+ // complicate the code for minimal benefit. Instead, add a phony
+ // target to let the developer manually run the validation if they so
+ // desire.
+ ctx.Phony("stub-validation", al.validationPaths...)
+ ctx.Phony(ctx.ModuleName()+"-stub-validation", al.validationPaths...)
+ if !ctx.Config().PartialCompileFlags().Disable_stub_validation {
+ al.addValidation(ctx, cmd, al.validationPaths)
+ }
generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles)
@@ -2789,6 +2876,13 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
setExtraJavaInfo(ctx, al, javaInfo)
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if al.stubsJar != nil {
+ moduleInfoJSON.ClassesJar = []string{al.stubsJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -3006,10 +3100,6 @@ func (j *Import) CreatedByJavaSdkLibraryName() *string {
return j.properties.Created_by_java_sdk_library_name
}
-func (a *Import) JacocoReportClassesFile() android.Path {
- return nil
-}
-
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs.GetOrDefault(ctx, nil)...)
@@ -3017,6 +3107,8 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
sdkDeps(ctx, android.SdkContext(j), j.dexer)
}
+
+ j.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
func (j *Import) commonBuildActions(ctx android.ModuleContext) {
@@ -3268,13 +3360,21 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
- Prebuilt: true,
+ Prebuilt: true,
+ PermittedPackages: j.properties.Permitted_packages,
})
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
buildComplianceMetadata(ctx)
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if j.combinedImplementationFile != nil {
+ moduleInfoJSON.ClassesJar = []string{j.combinedImplementationFile.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
@@ -3476,10 +3576,6 @@ func (j *DexImport) Stem() string {
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
-func (a *DexImport) JacocoReportClassesFile() android.Path {
- return nil
-}
-
func (j *DexImport) IsInstallable() bool {
return true
}
@@ -3498,7 +3594,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &j.dexpreopter)
- inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
+ inputJar := android.PathForModuleSrc(ctx, j.properties.Jars[0])
dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
if j.dexpreopter.uncompressedDex {
@@ -3544,6 +3640,8 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
javaInfo := &JavaInfo{}
setExtraJavaInfo(ctx, j, javaInfo)
+ javaInfo.BootDexJarPath = j.dexJarFile
+
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{})
@@ -3695,7 +3793,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy,
if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
// A shared SDK library. This should be added as a top-level CLC element.
sdkLib = &depName
- } else if lib := dep.SdkLibraryComponentDependencyInfo; lib != nil && lib.OptionalSdkLibraryImplementation != nil {
+ } else if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryComponentDependencyInfoProvider); ok && lib.OptionalSdkLibraryImplementation != nil {
if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation)+".impl" {
sdkLib = lib.OptionalSdkLibraryImplementation
}
@@ -3823,12 +3921,6 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo
}
}
- if slcDep, ok := module.(SdkLibraryComponentDependency); ok {
- javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{
- OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(),
- }
- }
-
if pul, ok := module.(ProvidesUsesLib); ok {
javaInfo.ProvidesUsesLibInfo = &ProvidesUsesLibInfo{
ProvidesUsesLib: pul.ProvidesUsesLib(),
@@ -3857,6 +3949,18 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo
javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx)
}
+ if ham, ok := module.(hiddenAPIModule); ok {
+ javaInfo.BootDexJarPath = ham.bootDexJar()
+ javaInfo.HiddenapiClassesJarPaths = ham.classesJars()
+ javaInfo.UncompressDexState = ham.uncompressDex()
+ }
+
+ if mm, ok := module.(interface {
+ MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel
+ }); ok {
+ javaInfo.MaxSdkVersion = mm.MaxSdkVersion(ctx)
+ }
+
if di, ok := module.(DexpreopterInterface); ok {
javaInfo.DexpreopterInfo = &DexpreopterInfo{
OutputProfilePathOnHost: di.OutputProfilePathOnHost(),
@@ -3869,4 +3973,16 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo
javaInfo.XrefJavaFiles = xr.XrefJavaFiles()
javaInfo.XrefKotlinFiles = xr.XrefKotlinFiles()
}
+
+ if sdk, ok := module.(android.SdkContext); ok {
+ javaInfo.SystemModules = sdk.SystemModules()
+ javaInfo.SdkVersion = sdk.SdkVersion(ctx)
+ }
+
+ if ap, ok := module.(ApexDependency); ok {
+ javaInfo.ApexDependencyInfo = &ApexDependencyInfo{
+ HeaderJars: ap.HeaderJars(),
+ ImplementationAndResourcesJars: ap.ImplementationAndResourcesJars(),
+ }
+ }
}
diff --git a/java/java_gob_enc.go b/java/java_gob_enc.go
new file mode 100644
index 000000000..69d21c8ab
--- /dev/null
+++ b/java/java_gob_enc.go
@@ -0,0 +1,54 @@
+// Code generated by go run gob_gen.go; DO NOT EDIT.
+
+package java
+
+import (
+ "bytes"
+ "github.com/google/blueprint/gobtools"
+)
+
+func init() {
+ ProguardSpecInfoGobRegId = gobtools.RegisterType(func() gobtools.CustomDec { return new(ProguardSpecInfo) })
+}
+
+func (r ProguardSpecInfo) Encode(buf *bytes.Buffer) error {
+ var err error
+
+ if err = gobtools.EncodeSimple(buf, r.Export_proguard_flags_files); err != nil {
+ return err
+ }
+
+ if err = r.ProguardFlagsFiles.EncodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.UnconditionallyExportedProguardFlags.EncodeInterface(buf); err != nil {
+ return err
+ }
+ return err
+}
+
+func (r *ProguardSpecInfo) Decode(buf *bytes.Reader) error {
+ var err error
+
+ err = gobtools.DecodeSimple[bool](buf, &r.Export_proguard_flags_files)
+ if err != nil {
+ return err
+ }
+
+ if err = r.ProguardFlagsFiles.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.UnconditionallyExportedProguardFlags.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ return err
+}
+
+var ProguardSpecInfoGobRegId int16
+
+func (r ProguardSpecInfo) GetTypeId() int16 {
+ return ProguardSpecInfoGobRegId
+}
diff --git a/java/java_test.go b/java/java_test.go
index 1ba78d49b..6e80dcd34 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2740,16 +2740,6 @@ func TestMultiplePrebuilts(t *testing.T) {
contents: ["%v"],
}
`
- hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool {
- t.Helper()
- var found bool
- ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
- if dep == wantDep {
- found = true
- }
- })
- return found
- }
hasFileWithStem := func(m android.TestingModule, stem string) bool {
t.Helper()
@@ -2793,7 +2783,8 @@ func TestMultiplePrebuilts(t *testing.T) {
// check that rdep gets the correct variation of dep
foo := ctx.ModuleForTests(t, "foo", "android_common")
expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common")
- android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
+ android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName),
+ true, android.HasDirectDep(ctx, foo.Module(), expectedDependency.Module()))
// check that output file of dep is always bar.jar
// The filename should be agnostic to source/prebuilt/prebuilt_version
@@ -2920,6 +2911,59 @@ func TestApiLibraryAconfigDeclarations(t *testing.T) {
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "flags-config-exportable.xml")
}
+func TestDroidstubsAconfigPropagation(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureMergeMockFs(map[string][]byte{
+ "a/A.java": nil,
+ "a/current.txt": nil,
+ "a/removed.txt": nil,
+ }),
+ ).RunTestWithBp(t, `
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package",
+ container: "com.android.foo",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ droidstubs {
+ name: "foo",
+ srcs: ["a/A.java"],
+ api_surface: "public",
+ check_api: {
+ current: {
+ api_file: "a/current.txt",
+ removed_api_file: "a/removed.txt",
+ }
+ },
+ aconfig_declarations: [
+ "bar",
+ ],
+ }
+
+ java_library {
+ name: "baz",
+ srcs: [
+ ":foo",
+ ],
+ }
+ `)
+
+ bazModule := result.ModuleForTests(t, "baz", "android_common").Module()
+ javaInfo, _ := android.OtherModuleProvider(result, bazModule, JavaInfoProvider)
+ aconfigProtos := javaInfo.AconfigIntermediateCacheOutputPaths
+
+ android.AssertIntEquals(t, "Expected to provide one aconfig proto file", 1, len(aconfigProtos))
+ android.AssertStringDoesContain(
+ t,
+ "Expected to provide bar/aconfig-cache.pb",
+ strings.Join(aconfigProtos.Strings(), " "),
+ "bar/aconfig-cache.pb",
+ )
+}
+
func TestTestOnly(t *testing.T) {
t.Parallel()
ctx := android.GroupFixturePreparers(
@@ -3150,7 +3194,7 @@ func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTe
}
}
- ctx.VisitAllModules(func(m blueprint.Module) {
+ ctx.VisitAllModules(func(m android.Module) {
addActuals(m, android.TestOnlyProviderKey)
})
@@ -3171,7 +3215,7 @@ func TestNativeRequiredDepOfJavaBinary(t *testing.T) {
t.Parallel()
findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module {
var ret []blueprint.Module
- ctx.VisitDirectDeps(module, func(dep blueprint.Module) {
+ ctx.VisitDirectDeps(module, func(dep android.Module) {
if dep.Name() == depName {
ret = append(ret, dep)
}
diff --git a/java/jdeps.go b/java/jdeps.go
index 56142c89b..c624e13bd 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -100,7 +100,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont
Rule: android.Touch,
Output: jfpath,
})
- ctx.DistForGoals([]string{"general-tests", "dist_files"}, j.outputPath)
+ ctx.DistForGoals([]string{"general-tests", "dist_files", "module-info"}, j.outputPath)
}
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
diff --git a/java/kotlin.go b/java/kotlin.go
index 308bb0305..68890bdda 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -26,25 +26,99 @@ import (
"github.com/google/blueprint"
)
-var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{Goma: true},
+type KotlinCompileData struct {
+ pcStateFileNew android.OutputPath
+ pcStateFilePrior android.OutputPath
+ diffFile android.OutputPath
+}
+
+const inputDeltaCmd = `${config.FindInputDeltaCmd} --target "$out" ` +
+ `--inputs_file "$out.rsp" --new_state "$newStateFile" --prior_state "$priorStateFile" > $sourceDeltaFile`
+
+const nonIncKotlinCmd = `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
+ `mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
+ `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` +
+ `${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
+ ` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
+ ` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
+ `${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
+ ` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
+ ` $kotlincFlags -jvm-target $kotlinJvmTarget $composePluginFlag $kotlincPluginFlags -Xbuild-file=$kotlinBuildFile ` +
+ ` -kotlin-home $emptyDir ` +
+ ` -Xplugin=${config.KotlinAbiGenPluginJar} ` +
+ ` -P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=$headerClassesDir && ` +
+ `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir -write_if_changed && ` +
+ `${config.SoongZipCmd} -jar -o $headerJar -C $headerClassesDir -D $headerClassesDir -write_if_changed && ` +
+ `rm -rf "$srcJarDir" "$classesDir" "$headerClassesDir" `
+
+const moveDeltaStateFile = `mv $newStateFile $priorStateFile && rm $sourceDeltaFile`
+
+var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports{},
blueprint.RuleParams{
- Command: `rm -rf "$classesDir" "$headerClassesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
- `mkdir -p "$classesDir" "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
+ Command: inputDeltaCmd + ` && ` + nonIncKotlinCmd + ` && ` + moveDeltaStateFile,
+ CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
+ "${config.KotlincCmd}",
+ "${config.KotlinCompilerJar}",
+ "${config.KotlinPreloaderJar}",
+ "${config.KotlinReflectJar}",
+ "${config.KotlinScriptRuntimeJar}",
+ "${config.KotlinStdlibJar}",
+ "${config.KotlinTrove4jJar}",
+ "${config.KotlinAnnotationJar}",
+ "${config.KotlinAbiGenPluginJar}",
+ "${config.GenKotlinBuildFileCmd}",
+ "${config.SoongZipCmd}",
+ "${config.ZipSyncCmd}",
+ },
+ Rspfile: "$out.rsp",
+ RspfileContent: `$in`,
+ Restat: true,
+ },
+ "kotlincFlags", "composePluginFlag", "kotlincPluginFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir",
+ "classesDir", "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir",
+ "newStateFile", "priorStateFile", "sourceDeltaFile", "name")
+
+// TODO: does incremental work with RBE?
+var kotlinIncremental = pctx.AndroidRemoteStaticRule("kotlin-incremental", android.RemoteRuleSupports{},
+ blueprint.RuleParams{
+ Command: // Incremental
+
+ inputDeltaCmd + ` && ` +
+
+ `if [ "$$SOONG_USE_PARTIAL_COMPILE" = "true" ]; then ` +
+ `rm -rf "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
+ `mkdir -p "$headerClassesDir" "$srcJarDir" "$emptyDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` +
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
- `${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
+ `${config.KotlinIncrementalClientBinary} ${config.KotlincGlobalFlags} ` +
` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
- ` $kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` +
- ` -kotlin-home $emptyDir ` +
+ ` $kotlincFlags $composeEmbeddablePluginFlag $kotlincPluginFlags ` +
+ ` -jvm-target $kotlinJvmTarget -build-file=$kotlinBuildFile ` +
+ ` -source-delta-file=$sourceDeltaFile` +
+ ` -kotlin-home=$emptyDir ` +
+ ` -root-dir=$incrementalRootDir` +
+ ` -output-dir=$outputDir` +
+ ` -build-dir=$buildDir ` +
+ ` -working-dir=$workDir ` +
` -Xplugin=${config.KotlinAbiGenPluginJar} ` +
` -P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=$headerClassesDir && ` +
`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir -write_if_changed && ` +
`${config.SoongZipCmd} -jar -o $headerJar -C $headerClassesDir -D $headerClassesDir -write_if_changed && ` +
- `rm -rf "$srcJarDir" "$classesDir" "$headerClassesDir"`,
+ `rm -rf "$srcJarDir" ; ` +
+
+ // Else non incremental
+ `else ` +
+ nonIncKotlinCmd + ` ; ` +
+ `fi && ` +
+ moveDeltaStateFile,
+
CommandDeps: []string{
+ "${config.FindInputDeltaCmd}",
"${config.KotlincCmd}",
+ "${config.KotlinIncrementalClientBinary}",
"${config.KotlinCompilerJar}",
"${config.KotlinPreloaderJar}",
"${config.KotlinReflectJar}",
@@ -61,8 +135,9 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
RspfileContent: `$in`,
Restat: true,
},
- "kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir",
- "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name")
+ "kotlincFlags", "composeEmbeddablePluginFlag", "composePluginFlag", "kotlincPluginFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "incrementalRootDir",
+ "classesDir", "headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir",
+ "name", "outputDir", "buildDir", "workDir", "newStateFile", "priorStateFile", "sourceDeltaFile")
var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
blueprint.RuleParams{
@@ -74,7 +149,7 @@ var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
// Skip header jars, those should not have an effect on kythe results.
` --args '${config.KotlincGlobalFlags} ` +
` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
- ` $kotlincFlags -jvm-target $kotlinJvmTarget ` +
+ ` $kotlincFlags $kotlincPluginFlags -jvm-target $kotlinJvmTarget ` +
`${config.KotlincKytheGlobalFlags}'`,
CommandDeps: []string{
"${config.KotlinKytheExtractor}",
@@ -83,7 +158,14 @@ var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
Rspfile: "$out.rsp",
RspfileContent: "$in",
},
- "classpath", "kotlincFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir",
+ "classpath", "kotlincFlags", "kotlincPluginFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir",
+)
+
+var kotlinIncrementalClean = pctx.AndroidStaticRule("kotlin-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "$cpSnapshot" "$outDir" "$buildDir" "$workDir"`,
+ },
+ "cpSnapshot", "outDir", "buildDir", "workDir",
)
func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath {
@@ -104,10 +186,10 @@ func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Path
// kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile.
func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath,
- srcFiles, commonSrcFiles, srcJars android.Paths,
- flags javaBuilderFlags) {
+ srcFiles, commonSrcFiles, srcJars android.Paths, flags javaBuilderFlags, compileData KotlinCompileData, incremental bool) {
var deps android.Paths
+ var orderOnlyDeps android.Paths
deps = append(deps, flags.kotlincClasspath...)
deps = append(deps, flags.kotlincDeps...)
deps = append(deps, srcJars...)
@@ -123,43 +205,97 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp
commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
}
+ associateJars := getAssociateJars(ctx, j.properties.Associates)
+ if len(associateJars) > 0 {
+ flags.kotlincFlags += " -Xfriend-paths=" + strings.Join(associateJars.Strings(), ",")
+ deps = append(deps, associateJars...)
+
+ // Prepend the associates classes jar in the classpath, so that they take priority over the other jars.
+ var newClasspath classpath
+ newClasspath = append(newClasspath, associateJars...)
+ newClasspath = append(newClasspath, flags.kotlincClasspath...)
+ flags.kotlincClasspath = newClasspath
+ }
+
classpathRspFile := android.PathForModuleOut(ctx, "kotlinc", "classpath.rsp")
android.WriteFileRule(ctx, classpathRspFile, strings.Join(flags.kotlincClasspath.Strings(), " "))
deps = append(deps, classpathRspFile)
+ rule := kotlinc
+ description := "kotlinc"
+ incrementalRootDir := android.PathForModuleOut(ctx, "kotlinc")
+ outputDir := "classes"
+ buildDir := "build"
+ workDir := "work"
+ args := map[string]string{
+ "classpath": classpathRspFile.String(),
+ "kotlincFlags": flags.kotlincFlags,
+ "kotlincPluginFlags": flags.kotlincPluginFlags,
+ "commonSrcFilesArg": commonSrcFilesArg,
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "classesDir": android.PathForModuleOut(ctx, "kotlinc", outputDir).String(),
+ "headerClassesDir": android.PathForModuleOut(ctx, "kotlinc", "header_classes").String(),
+ "headerJar": headerOutputFile.String(),
+ "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
+ "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
+ "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
+ "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
+ "name": kotlinName,
+ "newStateFile": compileData.pcStateFileNew.String(),
+ "priorStateFile": compileData.pcStateFilePrior.String(),
+ "sourceDeltaFile": compileData.diffFile.String(),
+ "composePluginFlag": flags.composePluginFlag,
+ }
+ if incremental {
+ rule = kotlinIncremental
+ description = "kotlin-incremental"
+ args["outputDir"] = outputDir
+ args["buildDir"] = buildDir
+ args["workDir"] = workDir
+ args["incrementalRootDir"] = incrementalRootDir.String()
+ args["sourceDeltaFile"] = compileData.diffFile.String()
+ args["composeEmbeddablePluginFlag"] = flags.composeEmbeddablePluginFlag
+ }
+
ctx.Build(pctx, android.BuildParams{
- Rule: kotlinc,
- Description: "kotlinc",
- Output: outputFile,
- ImplicitOutput: headerOutputFile,
- Inputs: srcFiles,
- Implicits: deps,
+ Rule: rule,
+ Description: description,
+ Inputs: srcFiles,
+ Implicits: deps,
+ OrderOnly: orderOnlyDeps,
+ Output: outputFile,
+ ImplicitOutputs: []android.WritablePath{headerOutputFile, compileData.pcStateFilePrior},
+ Args: args,
+ })
+
+ cleanPhonyPath := android.PathForModuleOut(ctx, "partialcompileclean", kotlinName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: kotlinIncrementalClean,
+ Description: "kotlin-partialcompileclean",
+ Output: cleanPhonyPath,
+ Inputs: android.Paths{},
Args: map[string]string{
- "classpath": classpathRspFile.String(),
- "kotlincFlags": flags.kotlincFlags,
- "commonSrcFilesArg": commonSrcFilesArg,
- "srcJars": strings.Join(srcJars.Strings(), " "),
- "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(),
- "headerClassesDir": android.PathForModuleOut(ctx, "kotlinc", "header_classes").String(),
- "headerJar": headerOutputFile.String(),
- "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
- "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
- "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
- "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
- "name": kotlinName,
+ // TODO: add this cp snapshot as a param to the incremental compiler.
+ "cpSnapshot": incrementalRootDir.Join(ctx, "shrunk-classpath-snapshot.bin").String(),
+ "outDir": incrementalRootDir.Join(ctx, outputDir).String(),
+ "buildDir": incrementalRootDir.Join(ctx, buildDir).String(),
+ "workDir": incrementalRootDir.Join(ctx, workDir).String(),
},
+ PhonyOutput: true,
})
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
// Emit kythe xref rule
if (ctx.Config().EmitXrefRules()) && ctx.Module() == ctx.PrimaryModule() {
extractionFile := outputFile.ReplaceExtension(ctx, "kzip")
args := map[string]string{
- "classpath": classpathRspFile.String(),
- "kotlincFlags": flags.kotlincFlags,
- "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
- "outJar": outputFile.String(),
- "srcJars": strings.Join(srcJars.Strings(), " "),
- "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(),
+ "classpath": classpathRspFile.String(),
+ "kotlincFlags": flags.kotlincFlags,
+ "kotlincPluginFlags": flags.kotlincPluginFlags,
+ "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
+ "outJar": outputFile.String(),
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(),
}
if commonSrcsList.Valid() {
args["commonSrcFilesList"] = "--common_srcs @" + commonSrcsList.String()
@@ -176,7 +312,49 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp
}
}
-var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{Goma: true},
+func getAssociateJars(ctx android.ModuleContext, associates []string) android.Paths {
+ if len(associates) == 0 {
+ return nil
+ }
+
+ associatesFound := make(map[string]bool)
+ for _, name := range associates {
+ associatesFound[name] = false
+ }
+
+ var associateJars android.Paths
+ ctx.VisitDirectDepsProxy(func(depModule android.ModuleProxy) {
+ depName := ctx.OtherModuleName(depModule)
+ _, isAssociate := associatesFound[depName]
+ if !isAssociate {
+ return
+ }
+
+ associatesFound[depName] = true
+ depInfo, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+ if !ok {
+ ctx.PropertyErrorf("Associates", "associate module '%s' is not a Java module", depName)
+ return
+ }
+
+ if len(depInfo.KotlinHeaderJars) == 0 {
+ ctx.PropertyErrorf("Associates", "associate module '%s' is not a Kotlin module", depName)
+ return
+ }
+
+ associateJars = append(associateJars, depInfo.KotlinHeaderJars...)
+ })
+
+ for name, found := range associatesFound {
+ if !found {
+ ctx.PropertyErrorf("Associates", "associate module '%s' must also be listed as a direct dependency (e.g. in static_libs or libs)", name)
+ }
+ }
+
+ return associateJars
+}
+
+var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{},
blueprint.RuleParams{
Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` +
`mkdir -p "$srcJarDir" "$kaptDir/sources" "$kaptDir/classes" && ` +
@@ -187,7 +365,8 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
`${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
`${config.KaptSuppressJDK9Warnings} ${config.KotlincSuppressJDK9Warnings} ` +
- `${config.JavacHeapFlags} $kotlincFlags -Xplugin=${config.KotlinKaptJar} ` +
+ `${config.JavacHeapFlags} $kotlincFlags ` +
+ `-Xplugin=${config.KotlinKaptJar} ` +
`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
`-P plugin:org.jetbrains.kotlin.kapt3:classes=$kaptDir/classes ` +
`-P plugin:org.jetbrains.kotlin.kapt3:stubs=$kaptDir/stubs ` +
@@ -198,7 +377,6 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
`$kaptProcessor ` +
`-Xbuild-file=$kotlinBuildFile && ` +
`${config.SoongZipCmd} -jar -write_if_changed -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` +
- `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.FindInputDeltaCmd}",
@@ -214,7 +392,7 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp
Restat: true,
},
"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor",
- "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir", "kotlinJvmTarget",
+ "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir",
"kotlinBuildFile", "name", "classesJarOut")
// kotlinKapt performs Kotlin-compatible annotation processing. It takes .kt and .java sources and srcjars, and runs
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 4b56cff1c..b2556b7af 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -199,6 +199,34 @@ func TestKotlin(t *testing.T) {
}
}
+func TestSortKotlincFlags(t *testing.T) {
+ t.Parallel()
+
+ t.Run("Successful sorting of kotlincFlags", func(t *testing.T) {
+ t.Parallel()
+ bp := `
+ java_library {
+ name: "Foo",
+ srcs: ["Foo.kt"],
+ kotlincflags: ["-Ja", "-Xb", "-JCz", "-JCy", "-JCx", "-Xd"]
+ }
+ `
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ module := result.ModuleForTests(t, "Foo", "android_common")
+ kotlincRule := module.Rule("kotlinc")
+ expectedFlags := "-Ja -JCz -JCy -JCx -Xb -Xd"
+
+ kotlincFlags := kotlincRule.Args["kotlincFlags"]
+ if !strings.Contains(kotlincFlags, expectedFlags) {
+ t.Errorf("kotlincFlags expected to have -J flags sorted first:\n Flags: %s\n Expected: %s", kotlincFlags, expectedFlags)
+ }
+ })
+
+}
+
func TestKapt(t *testing.T) {
t.Parallel()
bp := `
@@ -462,7 +490,7 @@ func TestKotlinCompose(t *testing.T) {
withCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
android.AssertStringDoesContain(t, "missing compose compiler plugin",
- withCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
+ withCompose.VariablesForTestsRelativeToTop()["composePluginFlag"], "-Xplugin="+composeCompiler.String())
android.AssertStringListContains(t, "missing kapt compose compiler dependency",
withCompose.Rule("kapt").Implicits.Strings(), composeCompiler.String())
@@ -471,7 +499,7 @@ func TestKotlinCompose(t *testing.T) {
noCompose.Rule("kotlinc").Implicits.Strings(), composeCompiler.String())
android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
- noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
+ noCompose.VariablesForTestsRelativeToTop()["composePluginFlag"], "-Xplugin="+composeCompiler.String())
}
func TestKotlinPlugin(t *testing.T) {
@@ -510,7 +538,7 @@ func TestKotlinPlugin(t *testing.T) {
withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
android.AssertStringDoesContain(t, "missing kotlin plugin",
- withKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
+ withKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincPluginFlags"], "-Xplugin="+kotlinPlugin.String())
android.AssertStringListContains(t, "missing kapt kotlin plugin dependency",
withKotlinPlugin.Rule("kapt").Implicits.Strings(), kotlinPlugin.String())
@@ -521,3 +549,95 @@ func TestKotlinPlugin(t *testing.T) {
android.AssertStringDoesNotContain(t, "unexpected kotlin plugin",
noKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
}
+
+func TestKotlinAssociates(t *testing.T) {
+ t.Parallel()
+
+ targets := []string{"FooUtils", "FooTest"}
+ for _, target := range targets {
+ t.Run("Successful associate linking of "+target, func(t *testing.T) {
+ t.Parallel()
+ bp := `
+ java_library {
+ name: "Foo",
+ srcs: ["Foo.kt"],
+ }
+
+ java_library {
+ name: "FooUtils",
+ srcs: ["FooUtils.kt"],
+ libs: ["Foo"],
+ associates: ["Foo"],
+ }
+
+ java_test {
+ name: "FooTest",
+ srcs: ["FooTest.kt"],
+ static_libs: ["Foo"],
+ associates: ["Foo"],
+ }
+ `
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ module := result.ModuleForTests(t, target, "android_common")
+ kotlincRule := module.Rule("kotlinc")
+ expectedFriendPath := "out/soong/.intermediates/Foo/android_common/kotlin_headers/Foo.jar"
+ expectedFlag := "-Xfriend-paths=" + expectedFriendPath
+
+ kotlincFlags := kotlincRule.Args["kotlincFlags"]
+ if !strings.Contains(kotlincFlags, expectedFlag) {
+ t.Errorf("kotlincFlags missing expected friend path:\n Flags: %s\n Expected: %s", kotlincFlags, expectedFlag)
+ }
+
+ classpathRspFile := module.Output("kotlinc/classpath.rsp")
+ classpathContent := android.ContentFromFileRuleForTests(t, result.TestContext, classpathRspFile)
+ classpathEntries := strings.Fields(classpathContent)
+ android.AssertStringPathRelativeToTopEquals(t, "first classpath entry", result.Config, expectedFriendPath, classpathEntries[0])
+ })
+ }
+
+ t.Run("Error: Associate not a dependency", func(t *testing.T) {
+ t.Parallel()
+ bp := `
+ java_library {
+ name: "Foo",
+ srcs: ["Foo.kt"],
+ }
+
+ java_library {
+ name: "FooUtils",
+ srcs: ["FooUtils.kt"],
+ associates: ["Foo"],
+ }
+ `
+ android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `\QAssociates: associate module 'Foo' must also be listed as a direct dependency\E`,
+ )).RunTestWithBp(t, bp)
+ })
+
+ t.Run("Error: Associate not a Kotlin module", func(t *testing.T) {
+ t.Parallel()
+ bp := `
+ java_library {
+ name: "Foo",
+ srcs: ["Foo.java"],
+ }
+
+ java_library {
+ name: "FooUtils",
+ srcs: ["FooUtils.kt"],
+ libs: ["Foo"],
+ associates: ["Foo"],
+ }
+ `
+ android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `\QAssociates: associate module 'Foo' is not a Kotlin module\E`,
+ )).RunTestWithBp(t, bp)
+ })
+}
diff --git a/java/lint.go b/java/lint.go
index dc1e51ffb..7f6c67a5a 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -28,6 +28,8 @@ import (
"android/soong/remoteexec"
)
+//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go
+
// lint checks automatically enforced for modules that have different min_sdk_version than
// sdk_version
var updatabilityChecks = []string{"NewApi"}
@@ -196,6 +198,7 @@ var allLintDatabasefiles = map[android.SdkKind]lintDatabaseFiles{
var LintProvider = blueprint.NewProvider[*LintInfo]()
+// @auto-generate: gob
type LintInfo struct {
HTML android.Path
Text android.Path
@@ -580,9 +583,31 @@ func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets, v
xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
lintZip(ctx, xmlList, xmlZip, validations)
+ android.SetProvider(ctx, ModuleLintReportZipsProvider, ModuleLintReportZipsInfo{
+ HtmlZip: htmlZip,
+ TextZip: textZip,
+ XmlZip: xmlZip,
+ })
+
return android.Paths{htmlZip, textZip, xmlZip}
}
+type ModuleLintReportZipsInfo struct {
+ HtmlZip android.Path
+ TextZip android.Path
+ XmlZip android.Path
+}
+
+func (i *ModuleLintReportZipsInfo) AllReports() android.Paths {
+ return android.Paths{
+ i.HtmlZip,
+ i.TextZip,
+ i.XmlZip,
+ }
+}
+
+var ModuleLintReportZipsProvider = blueprint.NewProvider[ModuleLintReportZipsInfo]()
+
type lintSingleton struct {
htmlZip android.WritablePath
textZip android.WritablePath
@@ -652,19 +677,20 @@ func copiedLintDatabaseFilesPath(ctx android.PathContext, name string) android.W
}
func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
+ // Dists of lint reports in unbundled builds is handled by unbundled_builder in unbundled.go
if ctx.Config().UnbundledBuild() {
return
}
var outputs []*LintInfo
- var dirs []string
ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
+ platformAvailabilitInfo := android.OtherModuleProviderOrDefault(ctx, m, android.PlatformAvailabilityInfoProvider)
if ctx.Config().KatiEnabled() && !commonInfo.ExportedToMake {
return
}
- if commonInfo.IsApexModule && commonInfo.NotAvailableForPlatform {
+ if commonInfo.IsApexModule && platformAvailabilitInfo.NotAvailableToPlatform {
apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider)
if apexInfo.IsForPlatform() {
// There are stray platform variants of modules in apexes that are not available for
@@ -678,8 +704,6 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
}
})
- dirs = android.SortedUniqueStrings(dirs)
-
zip := func(outputPath android.WritablePath, get func(*LintInfo) android.Path) {
var paths android.Paths
@@ -705,10 +729,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
zip(l.referenceBaselineZip, func(l *LintInfo) android.Path { return l.ReferenceBaseline })
ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
-
- if !ctx.Config().UnbundledBuild() {
- ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
- }
+ ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
func init() {
diff --git a/java/lint_gob_enc.go b/java/lint_gob_enc.go
new file mode 100644
index 000000000..9779a7639
--- /dev/null
+++ b/java/lint_gob_enc.go
@@ -0,0 +1,110 @@
+// Code generated by go run gob_gen.go; DO NOT EDIT.
+
+package java
+
+import (
+ "android/soong/android"
+ "bytes"
+ "github.com/google/blueprint/gobtools"
+)
+
+func init() {
+ LintInfoGobRegId = gobtools.RegisterType(func() gobtools.CustomDec { return new(LintInfo) })
+}
+
+func (r LintInfo) Encode(buf *bytes.Buffer) error {
+ var err error
+
+ if err = gobtools.EncodeInterface(buf, r.HTML); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeInterface(buf, r.Text); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeInterface(buf, r.XML); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeInterface(buf, r.ReferenceBaseline); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveHTML.EncodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveText.EncodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveXML.EncodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveBaseline.EncodeInterface(buf); err != nil {
+ return err
+ }
+ return err
+}
+
+func (r *LintInfo) Decode(buf *bytes.Reader) error {
+ var err error
+
+ if val2, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val2 == nil {
+ r.HTML = nil
+ } else {
+ r.HTML = val2.(android.Path)
+ }
+
+ if val4, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val4 == nil {
+ r.Text = nil
+ } else {
+ r.Text = val4.(android.Path)
+ }
+
+ if val6, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val6 == nil {
+ r.XML = nil
+ } else {
+ r.XML = val6.(android.Path)
+ }
+
+ if val8, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val8 == nil {
+ r.ReferenceBaseline = nil
+ } else {
+ r.ReferenceBaseline = val8.(android.Path)
+ }
+
+ if err = r.TransitiveHTML.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveText.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveXML.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = r.TransitiveBaseline.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ return err
+}
+
+var LintInfoGobRegId int16
+
+func (r LintInfo) GetTypeId() int16 {
+ return LintInfoGobRegId
+}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 155afc6c2..130f625e9 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -51,16 +51,16 @@ type platformBootclasspathModule struct {
properties platformBootclasspathProperties
// The apex:module pairs obtained from the configured modules.
- configuredModules []android.Module
+ configuredModules []android.ModuleProxy
// The apex:module pairs obtained from the fragments.
- fragments []android.Module
+ fragments []android.ModuleProxy
// The map of apex to the fragments they contain.
- apexNameToFragment map[string]android.Module
+ apexNameToFragment map[string]android.ModuleProxy
// The map of library modules in the bootclasspath to the fragments that contain them.
- libraryToApex map[android.Module]string
+ libraryToApex map[android.ModuleProxy]string
// Path to the monolithic hiddenapi-flags.csv file.
hiddenAPIFlagsCSV android.OutputPath
@@ -181,8 +181,8 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo
// Do not add implLibModule to allModules as the impl lib is only used to collect the
// transitive source files
- var implLibModule []android.Module
- ctx.VisitDirectDepsWithTag(platformBootclasspathImplLibDepTag, func(m android.Module) {
+ var implLibModule []android.ModuleProxy
+ ctx.VisitDirectDepsProxyWithTag(platformBootclasspathImplLibDepTag, func(m android.ModuleProxy) {
implLibModule = append(implLibModule, m)
})
@@ -251,7 +251,7 @@ func (b *platformBootclasspathModule) platformJars(ctx android.PathContext) andr
// checkPlatformModules ensures that the non-updatable modules supplied are not part of an
// apex module.
-func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleContext, modules []android.Module) {
+func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleContext, modules []android.ModuleProxy) {
// TODO(satayev): change this check to only allow core-icu4j, all apex jars should not be here.
for _, m := range modules {
apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider)
@@ -266,7 +266,7 @@ func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleCon
}
// checkApexModules ensures that the apex modules supplied are not from the platform.
-func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext, modules []android.Module) {
+func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext, modules []android.ModuleProxy) {
for _, m := range modules {
apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider)
fromUpdatableApex := apexInfo.Updatable
@@ -298,8 +298,10 @@ func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
-func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module,
- fragments []android.Module, libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) bootDexJarByModule {
+func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.ModuleProxy,
+ fragments []android.ModuleProxy, libraryToApex map[android.ModuleProxy]string,
+ apexNameToFragment map[string]android.ModuleProxy) bootDexJarByModule {
+
createEmptyHiddenApiFiles := func() {
paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
for _, path := range paths {
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index d2ec8bd4f..4d43ba9a6 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -44,8 +44,12 @@ func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext
}
type PlatformCompatConfigInfo struct {
- CompatConfig android.OutputPath
- SubDir string
+ CompatConfig android.OutputPath
+ SubDir string
+ CompatConfigMetadata android.Path
+ // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+ IncludeInMergedXml bool
+ Prebuilt bool
}
var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]()
@@ -99,14 +103,6 @@ type platformCompatConfigMetadataProvider interface {
includeInMergedXml() bool
}
-type PlatformCompatConfigMetadataInfo struct {
- CompatConfigMetadata android.Path
- // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
- IncludeInMergedXml bool
-}
-
-var PlatformCompatConfigMetadataInfoProvider = blueprint.NewProvider[PlatformCompatConfigMetadataInfo]()
-
type PlatformCompatConfigIntf interface {
android.Module
@@ -141,13 +137,11 @@ func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleCon
ctx.SetOutputFiles(android.Paths{p.configFile}, "")
android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{
- CompatConfig: p.CompatConfig(),
- SubDir: p.SubDir(),
- })
-
- android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+ CompatConfig: p.CompatConfig(),
+ SubDir: p.SubDir(),
CompatConfigMetadata: p.compatConfigMetadata(),
IncludeInMergedXml: p.includeInMergedXml(),
+ Prebuilt: false,
})
}
@@ -173,9 +167,9 @@ func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContex
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (b *compatConfigMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*platformCompatConfig)
- return ok
+func (b *compatConfigMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ info, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigInfoProvider)
+ return ok && !info.Prebuilt
}
func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
@@ -192,9 +186,8 @@ type compatConfigSdkMemberProperties struct {
Metadata android.Path
}
-func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- module := variant.(*platformCompatConfig)
- b.Metadata = module.metadataFile
+func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ b.Metadata = android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, PlatformCompatConfigInfoProvider).CompatConfigMetadata
}
func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -252,9 +245,10 @@ var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
- android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+ android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{
CompatConfigMetadata: module.compatConfigMetadata(),
IncludeInMergedXml: module.includeInMergedXml(),
+ Prebuilt: true,
})
}
@@ -280,7 +274,7 @@ func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.Singlet
if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
return
}
- if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigMetadataInfoProvider); ok {
+ if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigInfoProvider); ok {
if !android.IsModulePreferredProxy(ctx, module) {
return
}
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index 17fdae962..7d927fc0e 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -20,8 +20,6 @@ import (
"testing"
"android/soong/android"
-
- "github.com/google/blueprint"
)
func intPtr(v int) *int {
@@ -40,7 +38,7 @@ func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
).RunTest(t)
sdkSystemModules := []string{}
- result.VisitAllModules(func(module blueprint.Module) {
+ result.VisitAllModules(func(module android.Module) {
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
if strings.HasPrefix(name, "sdk_") && strings.HasSuffix(name, "_system_modules") {
sdkSystemModules = append(sdkSystemModules, name)
diff --git a/java/ravenwood.go b/java/ravenwood.go
index a942dc653..b096a2592 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -16,6 +16,7 @@ package java
import (
"strconv"
+ "android/soong/aconfig"
"android/soong/android"
"android/soong/tradefed"
@@ -37,14 +38,16 @@ var ravenwoodUtilsTag = dependencyTag{name: "ravenwoodutils"}
var ravenwoodRuntimeTag = dependencyTag{name: "ravenwoodruntime"}
var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"}
var ravenwoodTestInstResourceApkTag = dependencyTag{name: "ravenwoodtest-inst-res-apk"}
+var allAconfigModuleTag = dependencyTag{name: "all_aconfig"}
var genManifestProperties = pctx.AndroidStaticRule("genManifestProperties",
blueprint.RuleParams{
Command: "echo targetSdkVersionInt=$targetSdkVersionInt > $out && " +
"echo targetSdkVersionRaw=$targetSdkVersionRaw >> $out && " +
"echo packageName=$packageName >> $out && " +
- "echo instPackageName=$instPackageName >> $out",
- }, "targetSdkVersionInt", "targetSdkVersionRaw", "packageName", "instPackageName")
+ "echo instPackageName=$instPackageName >> $out && " +
+ "echo instrumentationClass=$instrumentationClass >> $out",
+ }, "targetSdkVersionInt", "targetSdkVersionRaw", "packageName", "instPackageName", "instrumentationClass")
const ravenwoodUtilsName = "ravenwood-utils"
const ravenwoodRuntimeName = "ravenwood-runtime"
@@ -87,8 +90,12 @@ type ravenwoodTestProperties struct {
// Specify the package name of this test module.
// This will be set to the test Context's package name.
- //(i.e. Instrumentation.getContext().getPackageName())
+ // (i.e. Instrumentation.getContext().getPackageName())
Inst_package_name *string
+
+ // Specify the name of the Instrumentation subclass to use.
+ // (e.g. "androidx.test.runner.AndroidJUnitRunner")
+ Instrumentation_class *string
}
type ravenwoodTest struct {
@@ -97,7 +104,9 @@ type ravenwoodTest struct {
ravenwoodTestProperties ravenwoodTestProperties
testProperties testProperties
- testConfig android.Path
+
+ testConfig android.Path
+ data android.Paths
forceOSType android.OsType
forceArchType android.ArchType
@@ -168,13 +177,31 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
r.forceArchType = ctx.Config().BuildArch
r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
- TestConfigProp: r.testProperties.Test_config,
- TestConfigTemplateProp: r.testProperties.Test_config_template,
- TestSuites: r.testProperties.Test_suites,
- AutoGenConfig: r.testProperties.Auto_gen_config,
- DeviceTemplate: "${RavenwoodTestConfigTemplate}",
- HostTemplate: "${RavenwoodTestConfigTemplate}",
+ TestConfigProp: r.testProperties.Test_config,
+ TestConfigTemplateProp: r.testProperties.Test_config_template,
+ OptionsForAutogenerated: r.testProperties.Test_options.Tradefed_options,
+ TestRunnerOptions: r.testProperties.Test_options.Test_runner_options,
+ TestSuites: r.testProperties.Test_suites,
+ AutoGenConfig: r.testProperties.Auto_gen_config,
+ DeviceTemplate: "${RavenwoodTestConfigTemplate}",
+ HostTemplate: "${RavenwoodTestConfigTemplate}",
})
+ r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_prefer32_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Host_common_data)...)
+
+ r.data = android.SortedUniquePaths(r.data)
+
+ var testData []android.DataPath
+ for _, data := range r.data {
+ dataPath := android.DataPath{SrcPath: data}
+ testData = append(testData, dataPath)
+ }
+ for _, d := range r.extraOutputFiles {
+ testData = append(testData, android.DataPath{SrcPath: d})
+ }
// Always enable Ravenizer for ravenwood tests.
r.Library.ravenizer.enabled = true
@@ -244,20 +271,28 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
targetSdkVersionInt := r.TargetSdkVersion(ctx).FinalOrFutureInt() // FinalOrFutureInt may be 10000.
packageName := proptools.StringDefault(r.ravenwoodTestProperties.Package_name, "")
instPackageName := proptools.StringDefault(r.ravenwoodTestProperties.Inst_package_name, "")
+ instClassName := proptools.StringDefault(r.ravenwoodTestProperties.Instrumentation_class, "")
ctx.Build(pctx, android.BuildParams{
Rule: genManifestProperties,
Description: "genManifestProperties",
Output: propertiesOutputPath,
Args: map[string]string{
- "targetSdkVersionInt": strconv.Itoa(targetSdkVersionInt),
- "targetSdkVersionRaw": targetSdkVersion,
- "packageName": packageName,
- "instPackageName": instPackageName,
+ "targetSdkVersionInt": strconv.Itoa(targetSdkVersionInt),
+ "targetSdkVersionRaw": targetSdkVersion,
+ "packageName": packageName,
+ "instPackageName": instPackageName,
+ "instrumentationClass": instClassName,
},
})
installProps := ctx.InstallFile(installPath, "ravenwood.properties", propertiesOutputPath)
installDeps = append(installDeps, installProps)
+ // Copy data files
+ for _, data := range r.data {
+ installedData := ctx.InstallFile(installPath, data.Rel(), data)
+ installDeps = append(installDeps, installedData)
+ }
+
// Install our JAR with all dependencies
ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
@@ -338,6 +373,10 @@ func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs.GetOrDefault(ctx, nil) {
ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
}
+
+ if r.Name() == ravenwoodRuntimeName {
+ ctx.AddVariationDependencies(nil, allAconfigModuleTag, aconfig.AllAconfigModule)
+ }
}
func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -355,11 +394,17 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex
names: jniDepNames,
})
+ install := func(to android.InstallPath, srcs ...android.Path) {
+ for _, s := range srcs {
+ ctx.InstallFile(to, s.Base(), s)
+ }
+ }
+
// Install our runtime into expected location for packaging
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
for _, lib := range r.ravenwoodLibgroupProperties.Libs {
libModule := ctx.GetDirectDepProxyWithTag(lib, ravenwoodLibContentTag)
- if libModule == nil {
+ if libModule.IsNil() {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{lib})
} else {
@@ -368,24 +413,50 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex
continue
}
libJar := android.OutputFileForModule(ctx, libModule, "")
- ctx.InstallFile(installPath, lib+".jar", libJar)
+ ctx.InstallFile(installPath, libJar.Base(), libJar)
}
soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
for _, jniLib := range jniLibs {
- ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
+ install(soInstallPath, jniLib.path)
}
dataInstallPath := installPath.Join(ctx, "ravenwood-data")
data := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Data)
for _, file := range data {
- ctx.InstallFile(dataInstallPath, file.Base(), file)
+ install(dataInstallPath, file)
}
fontsInstallPath := installPath.Join(ctx, "fonts")
fonts := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Fonts)
for _, file := range fonts {
- ctx.InstallFile(fontsInstallPath, file.Base(), file)
+ install(fontsInstallPath, file)
+ }
+
+ // Copy aconfig flag storage files.
+ if r.Name() == ravenwoodRuntimeName {
+ allAconfigFound := false
+ if allAconfig := ctx.GetDirectDepProxyWithTag(aconfig.AllAconfigModule, allAconfigModuleTag); !allAconfig.IsNil() {
+ aadi, ok := android.OtherModuleProvider(ctx, allAconfig, aconfig.AllAconfigDeclarationsInfoProvider)
+ if ok {
+ // Binary proto file and the text proto.
+ // We don't really use the text proto file, but having this would make debugging easier.
+ install(installPath.Join(ctx, "aconfig/metadata/aconfig/etc"), aadi.ParsedFlagsFile, aadi.TextProtoFlagsFile)
+
+ // The "new" storage files.
+ install(installPath.Join(ctx, "aconfig/metadata/aconfig/maps"), aadi.StoragePackageMap, aadi.StorageFlagMap)
+ install(installPath.Join(ctx, "aconfig/metadata/aconfig/boot"), aadi.StorageFlagVal, aadi.StorageFlagInfo)
+
+ allAconfigFound = true
+ }
+ }
+ if !allAconfigFound {
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{aconfig.AllAconfigModule})
+ } else {
+ ctx.ModuleErrorf("missing dependency %q", aconfig.AllAconfigModule)
+ }
+ }
}
// Normal build should perform install steps
diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go
index d6493bcfa..55084bf22 100644
--- a/java/ravenwood_test.go
+++ b/java/ravenwood_test.go
@@ -15,6 +15,7 @@
package java
import (
+ "android/soong/aconfig"
"runtime"
"testing"
@@ -27,6 +28,9 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers(
RegisterRavenwoodBuildComponents(ctx)
}),
android.FixtureAddTextFile("ravenwood/Android.bp", `
+ all_aconfig_declarations {
+ name: "all_aconfig_declarations",
+ }
cc_library_shared {
name: "ravenwood-runtime-jni1",
host_supported: true,
@@ -55,6 +59,11 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers(
srcs: ["Services.java"],
}
java_library_static {
+ name: "ravenwood-runtime-extra",
+ stem: "runtime-extra",
+ srcs: ["Extra.java"],
+ }
+ java_library_static {
name: "framework-rules.ravenwood",
srcs: ["Rules.java"],
}
@@ -79,6 +88,7 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers(
libs: [
"framework-minus-apex.ravenwood",
"framework-services.ravenwood",
+ "ravenwood-runtime-extra",
],
jni_libs: [
"ravenwood-runtime-jni1",
@@ -111,6 +121,7 @@ func TestRavenwoodRuntime(t *testing.T) {
ctx := android.GroupFixturePreparers(
PrepareForIntegrationTestWithJava,
etc.PrepareForTestWithPrebuiltEtc,
+ aconfig.PrepareForTestWithAconfigBuildComponents,
prepareRavenwoodRuntime,
).RunTest(t)
@@ -124,11 +135,20 @@ func TestRavenwoodRuntime(t *testing.T) {
runtime := ctx.ModuleForTests(t, "ravenwood-runtime", "android_common")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-minus-apex.ravenwood.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/framework-services.ravenwood.jar")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/runtime-extra.jar")
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni1.so")
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/libred.so")
runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so")
runtime.Output(installPathPrefix + "/ravenwood-runtime/ravenwood-data/app1.apk")
runtime.Output(installPathPrefix + "/ravenwood-runtime/fonts/Font.ttf")
+
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/etc/all_aconfig_declarations.pb")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/etc/all_aconfig_declarations.textproto")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/maps/all_aconfig_declarations.package.map")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/maps/all_aconfig_declarations.flag.map")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/boot/all_aconfig_declarations.flag.info")
+ runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/boot/all_aconfig_declarations.val")
+
utils := ctx.ModuleForTests(t, "ravenwood-utils", "android_common")
utils.Output(installPathPrefix + "/ravenwood-utils/framework-rules.ravenwood.jar")
}
@@ -142,6 +162,7 @@ func TestRavenwoodTest(t *testing.T) {
ctx := android.GroupFixturePreparers(
PrepareForIntegrationTestWithJava,
etc.PrepareForTestWithPrebuiltEtc,
+ aconfig.PrepareForTestWithAconfigBuildComponents,
prepareRavenwoodRuntime,
).RunTestWithBp(t, `
cc_library_shared {
@@ -176,12 +197,17 @@ func TestRavenwoodTest(t *testing.T) {
"jni-lib1",
"ravenwood-runtime-jni2",
],
+ data: [
+ "data/file1.txt",
+ "data2/sub/file2",
+ ],
resource_apk: "app2",
inst_resource_apk: "app3",
sdk_version: "test_current",
target_sdk_version: "34",
package_name: "a.b.c",
inst_package_name: "x.y.z",
+ instrumentation_class: "androidx.test.runner.AndroidJUnitRunner",
}
android_ravenwood_test {
name: "ravenwood-test-empty",
@@ -213,6 +239,8 @@ func TestRavenwoodTest(t *testing.T) {
module.Output(installPathPrefix + "/ravenwood-test/lib64/libpink.so")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-inst-res.apk")
+ module.Output(installPathPrefix + "/ravenwood-test/data/file1.txt")
+ module.Output(installPathPrefix + "/ravenwood-test/data2/sub/file2")
module = ctx.ModuleForTests(t, "ravenwood-test-empty", "android_common")
module.Output(installPathPrefix + "/ravenwood-test-empty/ravenwood.properties")
diff --git a/java/robolectric.go b/java/robolectric.go
index 1d204a4e0..cee194777 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -149,6 +149,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
extraTestRunnerOptions = append(extraTestRunnerOptions, tradefed.Option{Name: "java-flags", Value: "-Drobolectric.strict.mode=true"})
}
+ extraTestRunnerOptions = append(extraTestRunnerOptions, r.testProperties.Test_options.Test_runner_options...)
var extraOptions []tradefed.Option
var javaHome = ctx.Config().Getenv("ANDROID_JAVA_HOME")
@@ -406,7 +407,7 @@ func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleCont
if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
runtimeFromSourceModule := ctx.GetDirectDepProxyWithTag(String(r.props.Lib), libTag)
- if runtimeFromSourceModule == nil {
+ if runtimeFromSourceModule.IsNil() {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{String(r.props.Lib)})
} else {
diff --git a/java/rro.go b/java/rro.go
index 4ae8d7fc7..57b9da052 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -213,6 +213,11 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
Theme: r.Theme(),
})
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: r.Certificate(),
+ Name: r.outputFile.Base(),
+ })
+
ctx.SetOutputFiles([]android.Path{r.outputFile}, "")
buildComplianceMetadata(ctx)
@@ -261,6 +266,17 @@ func RuntimeResourceOverlayFactory() android.Module {
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.properties.Overrides)
+
+ module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
+ // Make this module product_specific by default. Keep this in sync with rroPartition()
+ if !ctx.DeviceSpecific() && !ctx.SocSpecific() && !ctx.SystemExtSpecific() {
+ proptools.AppendMatchingProperties(ctx.Module().GetProperties(), &struct {
+ Product_specific *bool
+ }{
+ Product_specific: proptools.BoolPtr(true),
+ }, nil)
+ }
+ })
return module
}
@@ -358,12 +374,12 @@ func (a *AutogenRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.
}
var rroDirs android.Paths
// Get rro dirs of the base app
- ctx.VisitDirectDepsWithTag(rroDepTag, func(m android.Module) {
- aarDep, _ := m.(AndroidLibraryDependency)
+ ctx.VisitDirectDepsProxyWithTag(rroDepTag, func(m android.ModuleProxy) {
+ javaInfo, _ := android.OtherModuleProvider(ctx, m, JavaInfoProvider)
if ctx.InstallInProduct() {
- rroDirs = filterRRO(aarDep.RRODirsDepSet(), product)
+ rroDirs = filterRRO(javaInfo.AndroidLibraryDependencyInfo.RRODirsDepSet, product)
} else {
- rroDirs = filterRRO(aarDep.RRODirsDepSet(), device)
+ rroDirs = filterRRO(javaInfo.AndroidLibraryDependencyInfo.RRODirsDepSet, device)
}
})
@@ -421,6 +437,11 @@ func (a *AutogenRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.
OutputFile: signed,
Certificate: a.certificate,
})
+
+ android.SetProvider(ctx, ApkCertInfoProvider, ApkCertInfo{
+ Certificate: a.certificate,
+ Name: signed.Base(),
+ })
}
func (a *AutogenRuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
diff --git a/java/rro_test.go b/java/rro_test.go
index 3e4fed51e..faf82af84 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -355,7 +355,7 @@ func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) {
android.AssertStringDoesContain(t,
"aapt2 link command expected to pass feature flags arguments",
linkInFlags,
- "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt",
)
}
diff --git a/java/sdk.go b/java/sdk.go
index d676164e9..d1c7c0112 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -99,7 +99,7 @@ func systemModuleKind(sdkKind android.SdkKind, apiLevel android.ApiLevel) androi
return systemModuleKind
}
-func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
+func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext SdkVersionContext) sdkDep {
sdkVersion := sdkContext.SdkVersion(ctx)
if !sdkVersion.Valid() {
ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.Raw)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 00ba8b2fb..4eec2ff35 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -17,9 +17,11 @@ package java
import (
"errors"
"fmt"
+ "maps"
"path"
"path/filepath"
"reflect"
+ "slices"
"sort"
"strings"
"sync"
@@ -38,11 +40,11 @@ type scopeDependencyTag struct {
apiScope *apiScope
// Function for extracting appropriate path information from the dependency.
- depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error
+ depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.ModuleProxy) error
}
// Extract tag specific information from the dependency.
-func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
+func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.ModuleProxy, paths *scopePaths) {
err := tag.depInfoExtractor(paths, ctx, dep)
if err != nil {
ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
@@ -697,7 +699,7 @@ type scopePaths struct {
latestRemovedApiPaths android.Paths
}
-func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error {
if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
paths.stubsHeaderPath = lib.HeaderJars
paths.stubsImplPath = lib.ImplementationJars
@@ -711,7 +713,7 @@ func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.Modul
}
}
-func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error {
if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
paths.stubsHeaderPath = lib.HeaderJars
if !ctx.Config().ReleaseHiddenApiExportableStubs() {
@@ -726,7 +728,7 @@ func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx and
}
}
-func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error {
if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
if ctx.Config().ReleaseHiddenApiExportableStubs() {
paths.stubsImplPath = lib.ImplementationJars
@@ -740,7 +742,7 @@ func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx and
}
}
-func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.Module,
+func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.ModuleProxy,
action func(*DroidStubsInfo, *StubsSrcInfo) error) error {
apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider)
if !ok {
@@ -755,7 +757,7 @@ func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, d
}
func (paths *scopePaths) treatDepAsApiStubsSrcProvider(
- ctx android.ModuleContext, dep android.Module, action func(provider *StubsSrcInfo) error) error {
+ ctx android.ModuleContext, dep android.ModuleProxy, action func(provider *StubsSrcInfo) error) error {
if apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider); ok {
err := action(&apiStubsProvider)
if err != nil {
@@ -797,7 +799,7 @@ func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider *S
return err
}
-func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.ModuleProxy) error {
stubsType := Everything
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
@@ -807,7 +809,7 @@ func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext
})
}
-func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.ModuleProxy) error {
stubsType := Everything
if ctx.Config().ReleaseHiddenApiExportableStubs() {
stubsType = Exportable
@@ -819,7 +821,7 @@ func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx an
})
}
-func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.Paths, error) {
+func extractOutputPaths(ctx android.ModuleContext, dep android.ModuleProxy) (android.Paths, error) {
var paths android.Paths
if sourceFileProducer, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
paths = sourceFileProducer.Srcs
@@ -829,13 +831,13 @@ func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.
}
}
-func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.ModuleProxy) error {
outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestApiPaths = outputPaths
return err
}
-func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
+func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.ModuleProxy) error {
outputPaths, err := extractOutputPaths(ctx, dep)
paths.latestRemovedApiPaths = outputPaths
return err
@@ -1022,6 +1024,12 @@ func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.Mod
ExportableStubDexJarPaths: exportableStubPaths,
RemovedTxtFiles: removedApiFilePaths,
SharedLibrary: c.sharedLibrary(),
+ DoctagPaths: c.doctagPaths,
+ OnBootclasspathSince: c.commonSdkLibraryProperties.On_bootclasspath_since,
+ OnBootclasspathBefore: c.commonSdkLibraryProperties.On_bootclasspath_before,
+ MinDeviceSdk: c.commonSdkLibraryProperties.Min_device_sdk,
+ MaxDeviceSdk: c.commonSdkLibraryProperties.Max_device_sdk,
+ ImplLibProfileGuided: c.implLibraryInfo != nil && c.implLibraryInfo.ProfileGuided,
}
}
@@ -1166,13 +1174,13 @@ func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(module android.M
module.AddProperties(&e.sdkLibraryComponentProperties)
}
-// to satisfy SdkLibraryComponentDependency
func (e *EmbeddableSdkLibraryComponent) SdkLibraryName() *string {
return e.sdkLibraryComponentProperties.SdkLibraryName
}
-// to satisfy SdkLibraryComponentDependency
-func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string {
+var SdkLibraryComponentDependencyInfoProvider = blueprint.NewMutatorProvider[SdkLibraryComponentDependencyInfo]("deps")
+
+type SdkLibraryComponentDependencyInfo struct {
// For shared libraries, this is the same as the SDK library name. If a Java library or app
// depends on a component library (e.g. a stub library) it still needs to know the name of the
// run-time library and the corresponding module that provides the implementation. This name is
@@ -1181,28 +1189,29 @@ func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *stri
//
// For non-shared SDK (component or not) libraries this returns `nil`, as they are not
// <uses-library> and should not be added to the manifest or to CLC.
- return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
+ OptionalSdkLibraryImplementation *string
+ // The name of the java_sdk_library/_import module if this module was created by one.
+ SdkLibraryName *string
}
-// Implemented by modules that are (or possibly could be) a component of a java_sdk_library
-// (including the java_sdk_library) itself.
-type SdkLibraryComponentDependency interface {
- UsesLibraryDependency
-
- // SdkLibraryName returns the name of the java_sdk_library/_import module.
- SdkLibraryName() *string
+func (e *EmbeddableSdkLibraryComponent) setComponentDependencyInfoProvider(ctx android.BottomUpMutatorContext) {
+ android.SetProvider(ctx, SdkLibraryComponentDependencyInfoProvider, SdkLibraryComponentDependencyInfo{
+ OptionalSdkLibraryImplementation: e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack,
+ SdkLibraryName: e.sdkLibraryComponentProperties.SdkLibraryName,
+ })
+}
- // The name of the implementation library for the optional SDK library or nil, if there isn't one.
- OptionalSdkLibraryImplementation() *string
+type ApiScopePathsInfo struct {
+ StubsImplPath android.Paths
+ CurrentApiFilePath android.OptionalPath
+ RemovedApiFilePath android.OptionalPath
+ StubsSrcJar android.OptionalPath
+ AnnotationsZip android.OptionalPath
}
-// Make sure that all the module types that are components of java_sdk_library/_import
-// and which can be referenced (directly or indirectly) from an android app implement
-// the SdkLibraryComponentDependency interface.
-var _ SdkLibraryComponentDependency = (*Library)(nil)
-var _ SdkLibraryComponentDependency = (*Import)(nil)
-var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
-var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil)
+type ApiScopePropsInfo struct {
+ SdkVersion *string
+}
type SdkLibraryInfo struct {
// GeneratingLibs is the names of the library modules that this sdk library
@@ -1224,7 +1233,16 @@ type SdkLibraryInfo struct {
// Whether if this can be used as a shared library.
SharedLibrary bool
- Prebuilt bool
+ Prebuilt bool
+ DistStem string
+ DoctagPaths android.Paths
+ OnBootclasspathSince *string
+ OnBootclasspathBefore *string
+ MinDeviceSdk *string
+ MaxDeviceSdk *string
+ ImplLibProfileGuided bool
+ ApiScopePaths map[string]ApiScopePathsInfo
+ ApiScopeProps map[string]ApiScopePropsInfo
}
var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]()
@@ -1445,6 +1463,13 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
m += "Please see the documentation of the prebuilt_apis module type (and a usage example in prebuilts/sdk) for a convenient way to generate these."
ctx.ModuleErrorf(m)
}
+
+ module.usesLibrary.deps(ctx, false)
+
+ module.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
+ libDeps := ctx.AddVariationDependencies(nil, usesLibStagingTag, module.properties.Libs...)
+ libDeps = append(libDeps, ctx.AddVariationDependencies(nil, usesLibStagingTag, module.sdkLibraryProperties.Impl_only_libs...)...)
+ module.usesLibrary.depsFromLibs(ctx, libDeps)
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1505,6 +1530,7 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
module.bootDexJarPath = module.implLibraryInfo.BootDexJarPath
module.uncompressDexState = module.implLibraryInfo.UncompressDexState
module.active = module.implLibraryInfo.Active
+ module.classLoaderContexts = module.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
}
module.outputFile = module.implLibraryInfo.OutputFile
@@ -1519,7 +1545,7 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
// Properties required for Library.AndroidMkEntries
module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs
module.dexpreopter.builtInstalled = module.implLibraryInfo.BuiltInstalled
- module.jacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+ module.jacocoInfo = module.implLibraryInfo.JacocoInfo
module.dexer.proguardDictionary = module.implLibraryInfo.ProguardDictionary
module.dexer.proguardUsageZip = module.implLibraryInfo.ProguardUsageZip
module.linter.reports = module.implLibraryInfo.LinterReports
@@ -1532,9 +1558,9 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
module.hostdexInstallFile = module.implLibraryInfo.HostdexInstallFile
}
- if installFilesInfo, ok := android.OtherModuleProvider(ctx, implLib, android.InstallFilesProvider); ok {
- if installFilesInfo.CheckbuildTarget != nil {
- ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
+ if buildTargetsInfo, ok := android.OtherModuleProvider(ctx, implLib, android.ModuleBuildTargetsProvider); ok {
+ if buildTargetsInfo.CheckbuildTarget != nil {
+ ctx.CheckbuildFile(buildTargetsInfo.CheckbuildTarget)
}
}
}
@@ -1581,14 +1607,47 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
}
javaInfo := &JavaInfo{
- JacocoReportClassesFile: module.jacocoReportClassesFile,
+ JacocoInfo: module.jacocoInfo,
+ CompileDex: module.dexProperties.Compile_dex,
}
setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
android.SetProvider(ctx, JavaInfoProvider, javaInfo)
sdkLibInfo.GeneratingLibs = generatingLibs
sdkLibInfo.Prebuilt = false
+ sdkLibInfo.DistStem = module.distStem()
+ if module.scopePaths != nil {
+ sdkLibInfo.ApiScopePaths = make(map[string]ApiScopePathsInfo)
+ for k, v := range module.scopePaths {
+ sdkLibInfo.ApiScopePaths[k.name] = ApiScopePathsInfo{
+ StubsImplPath: v.stubsImplPath,
+ CurrentApiFilePath: v.currentApiFilePath,
+ RemovedApiFilePath: v.removedApiFilePath,
+ StubsSrcJar: v.stubsSrcJar,
+ AnnotationsZip: v.annotationsZip,
+ }
+ }
+ }
+ if module.scopeToProperties != nil {
+ sdkLibInfo.ApiScopeProps = make(map[string]ApiScopePropsInfo)
+ for k, v := range module.scopeToProperties {
+ sdkLibInfo.ApiScopeProps[k.name] = ApiScopePropsInfo{
+ SdkVersion: v.Sdk_version,
+ }
+ }
+ }
android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo)
+
+ android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{
+ PermittedPackages: module.PermittedPackagesForUpdatableBootJars(),
+ })
+
+ moduleInfoJSON := ctx.ModuleInfoJSON()
+ moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"}
+ if module.implementationAndResourcesJar != nil {
+ moduleInfoJSON.ClassesJar = []string{module.implementationAndResourcesJar.String()}
+ }
+ moduleInfoJSON.SystemSharedLibs = []string{"none"}
}
func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) {
@@ -1630,12 +1689,17 @@ func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
// Get the sdk version for use when compiling the stubs library.
func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope) string {
- scopeProperties := module.scopeToProperties[apiScope]
- if scopeProperties.Sdk_version != nil {
- return proptools.String(scopeProperties.Sdk_version)
+ return getSdkVersionForStubsLibrary(mctx, apiScope, module.scopeToProperties[apiScope].Sdk_version,
+ android.SdkContext(&module.Library))
+}
+
+func getSdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope,
+ sdkVersion *string, sdkContext SdkVersionContext) string {
+ if sdkVersion != nil {
+ return proptools.String(sdkVersion)
}
- sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library))
+ sdkDep := decodeSdkDep(mctx, sdkContext)
if sdkDep.hasStandardLibs() {
// If building against a standard sdk then use the sdk version appropriate for the scope.
return apiScope.sdkVersion
@@ -1797,11 +1861,17 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
panic(fmt.Sprintf("script file %s doesn't exist", script))
}
+ env_msg := ""
+ if mctx.Config().GetBuildFlagBool("RELEASE_SRC_DIR_IS_READ_ONLY") {
+ env_msg = "BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true "
+ }
+
mctx.ModuleErrorf("One or more current api files are missing. "+
"You can update them by:\n"+
- "%s %q %s && m update-api",
+ "%s %q %s && %sm update-api",
script, filepath.Join(mctx.ModuleDir(), apiDir),
- strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
+ strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "),
+ env_msg)
return
}
@@ -2076,6 +2146,12 @@ func (module *SdkLibraryImport) BaseModuleName() string {
return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
}
+func (module *SdkLibraryImport) sortedApiScopes() []*apiScope {
+ return slices.SortedFunc(maps.Keys(module.scopeProperties), func(a, b *apiScope) int {
+ return strings.Compare(a.name, b.name)
+ })
+}
+
func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
// If the build is configured to use prebuilts then force this to be preferred.
@@ -2083,7 +2159,8 @@ func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHo
module.prebuilt.ForcePrefer()
}
- for apiScope, scopeProperties := range module.scopeProperties {
+ for _, apiScope := range module.sortedApiScopes() {
+ scopeProperties := module.scopeProperties[apiScope]
if len(scopeProperties.Jars) == 0 {
continue
}
@@ -2108,7 +2185,8 @@ func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHo
// Add the dependencies on the child module in the component deps mutator so that it
// creates references to the prebuilt and not the source modules.
func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
- for apiScope, scopeProperties := range module.scopeProperties {
+ for _, apiScope := range module.sortedApiScopes() {
+ scopeProperties := module.scopeProperties[apiScope]
if len(scopeProperties.Jars) == 0 {
continue
}
@@ -2136,6 +2214,8 @@ func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext)
ctx.AddDependency(module, xmlPermissionsFileTag, xmlPermissionsModuleName)
}
}
+
+ module.EmbeddableSdkLibraryComponent.setComponentDependencyInfoProvider(ctx)
}
var _ android.ApexModule = (*SdkLibraryImport)(nil)
@@ -2202,7 +2282,8 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
sdkLibInfo := module.generateCommonBuildActions(ctx)
// Populate the scope paths with information from the properties.
- for apiScope, scopeProperties := range module.scopeProperties {
+ for _, apiScope := range module.sortedApiScopes() {
+ scopeProperties := module.scopeProperties[apiScope]
if len(scopeProperties.Jars) == 0 {
continue
}
@@ -2243,7 +2324,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
javaInfo := &JavaInfo{}
if module.implLibraryInfo != nil {
- javaInfo.JacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+ javaInfo.JacocoInfo = module.implLibraryInfo.JacocoInfo
}
setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
@@ -2283,16 +2364,7 @@ func (module *SdkLibraryImport) ClassLoaderContexts() dexpreopt.ClassLoaderConte
return nil
}
-// to satisfy apex.javaDependency interface
-func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
- if module.implLibraryInfo == nil {
- return nil
- } else {
- return module.implLibraryInfo.JacocoReportClassesFile
- }
-}
-
-// to satisfy apex.javaDependency interface
+// to satisfy apex.javaModule interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()
}
@@ -2341,9 +2413,9 @@ func (s *sdkLibrarySdkMemberType) AddDependencies(ctx android.SdkDependencyConte
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*SdkLibrary)
- return ok
+func (s *sdkLibrarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ info, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
+ return ok && !info.Prebuilt
}
func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
@@ -2436,49 +2508,70 @@ type scopeProperties struct {
SdkVersion string
}
-func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- sdk := variant.(*SdkLibrary)
+type SdkVersionContext interface {
+ SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec
+ SystemModules() string
+}
+
+type SdkVersionContextProviderImpl struct {
+ javaInfo *JavaInfo
+}
+
+func (s *SdkVersionContextProviderImpl) SdkVersion(_ android.EarlyModuleContext) android.SdkSpec {
+ return s.javaInfo.SdkVersion
+}
+func (s *SdkVersionContextProviderImpl) SystemModules() string {
+ return s.javaInfo.SystemModules
+}
+
+func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ mctx := ctx.SdkModuleContext()
+ javaInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, JavaInfoProvider)
+ libraryInfo := android.OtherModuleProviderOrDefault(mctx, variant, JavaLibraryInfoProvider)
+ sdkInfo := android.OtherModuleProviderOrDefault(mctx, variant, SdkLibraryInfoProvider)
// Copy the stem name for files in the sdk snapshot.
- s.Stem = sdk.distStem()
+ s.Stem = sdkInfo.DistStem
s.Scopes = make(map[*apiScope]*scopeProperties)
for _, apiScope := range AllApiScopes {
- paths := sdk.findScopePaths(apiScope)
- if paths == nil {
+ paths, ok := sdkInfo.ApiScopePaths[apiScope.name]
+ if !ok {
continue
}
- jars := paths.stubsImplPath
+ jars := paths.StubsImplPath
if len(jars) > 0 {
properties := scopeProperties{}
properties.Jars = jars
- properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope)
- properties.StubsSrcJar = paths.stubsSrcJar.Path()
- if paths.currentApiFilePath.Valid() {
- properties.CurrentApiFile = paths.currentApiFilePath.Path()
+ properties.SdkVersion = getSdkVersionForStubsLibrary(mctx, apiScope, sdkInfo.ApiScopeProps[apiScope.name].SdkVersion,
+ &SdkVersionContextProviderImpl{javaInfo})
+
+ properties.StubsSrcJar = paths.StubsSrcJar.Path()
+ if paths.CurrentApiFilePath.Valid() {
+ properties.CurrentApiFile = paths.CurrentApiFilePath.Path()
}
- if paths.removedApiFilePath.Valid() {
- properties.RemovedApiFile = paths.removedApiFilePath.Path()
+ if paths.RemovedApiFilePath.Valid() {
+ properties.RemovedApiFile = paths.RemovedApiFilePath.Path()
}
// The annotations zip is only available for modules that set annotations_enabled: true.
- if paths.annotationsZip.Valid() {
- properties.AnnotationsZip = paths.annotationsZip.Path()
+ if paths.AnnotationsZip.Valid() {
+ properties.AnnotationsZip = paths.AnnotationsZip.Path()
}
s.Scopes[apiScope] = &properties
}
}
- s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
- s.Compile_dex = sdk.dexProperties.Compile_dex
- s.Doctag_paths = sdk.doctagPaths
- s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars()
- s.On_bootclasspath_since = sdk.commonSdkLibraryProperties.On_bootclasspath_since
- s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before
- s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
- s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
+ s.Shared_library = proptools.BoolPtr(sdkInfo.SharedLibrary)
+ s.Compile_dex = javaInfo.CompileDex
+ s.Doctag_paths = sdkInfo.DoctagPaths
+ s.Permitted_packages = libraryInfo.PermittedPackages
+ s.On_bootclasspath_since = sdkInfo.OnBootclasspathSince
+ s.On_bootclasspath_before = sdkInfo.OnBootclasspathBefore
+ s.Min_device_sdk = sdkInfo.MinDeviceSdk
+ s.Max_device_sdk = sdkInfo.MaxDeviceSdk
- if sdk.implLibraryInfo != nil && sdk.implLibraryInfo.ProfileGuided {
+ if sdkInfo.ImplLibProfileGuided {
s.DexPreoptProfileGuided = proptools.BoolPtr(true)
}
}
diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go
index f5feabeb4..2d27c42f6 100644
--- a/java/sdk_library_internal.go
+++ b/java/sdk_library_internal.go
@@ -20,7 +20,9 @@ import (
"strings"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/etc"
+ "android/soong/java/config"
"github.com/google/blueprint/proptools"
)
@@ -168,6 +170,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
&module.dexpreoptProperties,
&module.linter.properties,
&module.overridableProperties,
+ &module.usesLibrary.usesLibraryProperties,
&props,
module.sdkComponentPropertiesForChildLibrary(),
}
@@ -581,7 +584,9 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
Min_device_sdk *string
Max_device_sdk *string
Sdk_library_min_api_level *string
- Uses_libs_dependencies proptools.Configurable[[]string]
+ Uses_libs proptools.Configurable[[]string]
+ Libs []string
+ Impl_only_libs []string
}{
Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
Enabled: module.EnabledProperty(),
@@ -592,7 +597,9 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk,
Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk,
Sdk_library_min_api_level: &moduleMinApiLevelStr,
- Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs.Clone(),
+ Uses_libs: module.usesLibraryProperties.Uses_libs.Clone(),
+ Libs: android.RemoveListFromList(module.properties.Libs, config.FrameworkLibraries),
+ Impl_only_libs: module.sdkLibraryProperties.Impl_only_libs,
}
mctx.CreateModule(sdkLibraryXmlFactory, &props)
@@ -716,6 +723,8 @@ type sdkLibraryXml struct {
installDirPath android.InstallPath
hideApexVariantFromMake bool
+
+ usesLibrary
}
type sdkLibraryXmlProperties struct {
@@ -754,10 +763,11 @@ type sdkLibraryXmlProperties struct {
// This value comes from the ApiLevel of the MinSdkVersion property.
Sdk_library_min_api_level *string
- // Uses-libs dependencies that the shared library requires to work correctly.
- //
- // This will add dependency="foo:bar" to the <library> section.
- Uses_libs_dependencies proptools.Configurable[[]string]
+ // List of java libraries that will be in the classpath.
+ Libs []string `android:"arch_variant"`
+
+ // List of Java libraries that will be in the classpath when building the implementation lib.
+ Impl_only_libs []string `android:"arch_variant"`
}
// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
@@ -765,7 +775,7 @@ type sdkLibraryXmlProperties struct {
func sdkLibraryXmlFactory() android.Module {
module := &sdkLibraryXml{}
- module.AddProperties(&module.properties)
+ module.AddProperties(&module.properties, &module.usesLibrary.usesLibraryProperties)
android.InitApexModule(module)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
@@ -801,7 +811,10 @@ func (module *sdkLibraryXml) ApexAvailableFor() []string {
}
func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
- // do nothing
+ module.usesLibrary.deps(ctx, false)
+ libDeps := ctx.AddVariationDependencies(nil, usesLibStagingTag, module.properties.Libs...)
+ libDeps = append(libDeps, ctx.AddVariationDependencies(nil, usesLibStagingTag, module.properties.Impl_only_libs...)...)
+ module.usesLibrary.depsFromLibs(ctx, libDeps)
}
var _ android.ApexModule = (*sdkLibraryXml)(nil)
@@ -865,8 +878,13 @@ func formattedOptionalAttribute(attrName string, value *string) string {
return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value)
}
-func formattedDependenciesAttribute(dependencies []string) string {
- if dependencies == nil {
+func (module *sdkLibraryXml) formattedDependenciesAttribute(ctx android.ModuleContext) string {
+ classLoaderContexts := module.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+ dependencies := make([]string, 0, len(classLoaderContexts[dexpreopt.AnySdkVersion]))
+ for _, dep := range classLoaderContexts[dexpreopt.AnySdkVersion] {
+ dependencies = append(dependencies, dep.Name)
+ }
+ if len(dependencies) == 0 {
return ""
}
return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":"))
@@ -881,7 +899,7 @@ func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) stri
implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
- dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies.GetOrDefault(ctx, nil))
+ dependenciesAttr := module.formattedDependenciesAttribute(ctx)
// <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
// similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
var libraryTag string
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 6d27e54d0..1f4b57e7d 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -180,11 +180,11 @@ func TestJavaSdkLibrary(t *testing.T) {
fooImplDexJar := result.ModuleForTests(t, "foo.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are NOT excluded from output of foo.impl.
- android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
+ android.AssertStringDoesNotContain(t, "foo.impl dex", fooImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/**/*.kotlin_module")
barImplDexJar := result.ModuleForTests(t, "bar.impl", "android_common").Rule("d8")
// tests if kotlinc generated files are excluded from output of bar.impl.
- android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
+ android.AssertStringDoesContain(t, "bar.impl dex", barImplDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/**/*.kotlin_module")
}
func TestJavaSdkLibrary_UpdatableLibrary(t *testing.T) {
diff --git a/java/system_modules.go b/java/system_modules.go
index e955aec15..5ced86efc 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -29,6 +29,8 @@ import (
// file will produce the rules necessary to convert each unique set of bootclasspath jars into
// system modules in a runtime image using the jmod and jlink tools.
+//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go
+
func init() {
RegisterSystemModulesBuildComponents(android.InitRegistrationContext)
@@ -121,6 +123,7 @@ func SystemModulesFactory() android.Module {
return module
}
+// @auto-generate: gob
type SystemModulesProviderInfo struct {
// The aggregated header jars from all jars specified in the libs property.
// Used when system module is added as a dependency to bootclasspath.
@@ -131,6 +134,8 @@ type SystemModulesProviderInfo struct {
// depset of header jars for this module and all transitive static dependencies
TransitiveStaticLibsHeaderJars depset.DepSet[android.Path]
+ Prebuilt bool
+ Libs []string
}
var SystemModulesProvider = blueprint.NewProvider[*SystemModulesProviderInfo]()
@@ -150,11 +155,21 @@ type SystemModulesProperties struct {
Libs []string
}
+func (system *systemModulesImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ info := system.commonBuildActions(ctx)
+ info.Prebuilt = true
+ android.SetProvider(ctx, SystemModulesProvider, info)
+}
+
func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ android.SetProvider(ctx, SystemModulesProvider, system.commonBuildActions(ctx))
+}
+
+func (system *SystemModules) commonBuildActions(ctx android.ModuleContext) *SystemModulesProviderInfo {
var jars android.Paths
var transitiveStaticLibsHeaderJars []depset.DepSet[android.Path]
- ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(systemModulesLibsTag, func(module android.ModuleProxy) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
jars = append(jars, dep.HeaderJars...)
transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
@@ -163,12 +178,13 @@ func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleConte
system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, jars)
- android.SetProvider(ctx, SystemModulesProvider, &SystemModulesProviderInfo{
+ return &SystemModulesProviderInfo{
HeaderJars: jars,
OutputDir: system.outputDir,
OutputDirDeps: system.outputDeps,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, nil, transitiveStaticLibsHeaderJars),
- })
+ Libs: system.properties.Libs,
+ }
}
// ComponentDepsMutator is called before prebuilt modules without a corresponding source module are
@@ -275,12 +291,11 @@ func (mt *systemModulesSdkMemberType) AddDependencies(ctx android.SdkDependencyC
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (mt *systemModulesSdkMemberType) IsInstance(module android.Module) bool {
- if _, ok := module.(*SystemModules); ok {
+func (mt *systemModulesSdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ if info, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
// A prebuilt system module cannot be added as a member of an sdk because the source and
// snapshot instances would conflict.
- _, ok := module.(*systemModulesImport)
- return !ok
+ return !info.Prebuilt
}
return false
}
@@ -299,9 +314,8 @@ func (mt *systemModulesSdkMemberType) CreateVariantPropertiesStruct() android.Sd
return &systemModulesInfoProperties{}
}
-func (p *systemModulesInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- systemModule := variant.(*SystemModules)
- p.Libs = systemModule.properties.Libs
+func (p *systemModulesInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ p.Libs = android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, SystemModulesProvider).Libs
}
func (p *systemModulesInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
diff --git a/java/system_modules_gob_enc.go b/java/system_modules_gob_enc.go
new file mode 100644
index 000000000..7585318b4
--- /dev/null
+++ b/java/system_modules_gob_enc.go
@@ -0,0 +1,137 @@
+// Code generated by go run gob_gen.go; DO NOT EDIT.
+
+package java
+
+import (
+ "android/soong/android"
+ "bytes"
+ "github.com/google/blueprint/gobtools"
+)
+
+func init() {
+ SystemModulesProviderInfoGobRegId = gobtools.RegisterType(func() gobtools.CustomDec { return new(SystemModulesProviderInfo) })
+}
+
+func (r SystemModulesProviderInfo) Encode(buf *bytes.Buffer) error {
+ var err error
+
+ if err = gobtools.EncodeSimple(buf, int32(len(r.HeaderJars))); err != nil {
+ return err
+ }
+ for val1 := 0; val1 < len(r.HeaderJars); val1++ {
+ if err = gobtools.EncodeInterface(buf, r.HeaderJars[val1]); err != nil {
+ return err
+ }
+ }
+
+ if err = gobtools.EncodeInterface(buf, r.OutputDir); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeSimple(buf, int32(len(r.OutputDirDeps))); err != nil {
+ return err
+ }
+ for val2 := 0; val2 < len(r.OutputDirDeps); val2++ {
+ if err = gobtools.EncodeInterface(buf, r.OutputDirDeps[val2]); err != nil {
+ return err
+ }
+ }
+
+ if err = r.TransitiveStaticLibsHeaderJars.EncodeInterface(buf); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeSimple(buf, r.Prebuilt); err != nil {
+ return err
+ }
+
+ if err = gobtools.EncodeSimple(buf, int32(len(r.Libs))); err != nil {
+ return err
+ }
+ for val3 := 0; val3 < len(r.Libs); val3++ {
+ if err = gobtools.EncodeString(buf, r.Libs[val3]); err != nil {
+ return err
+ }
+ }
+ return err
+}
+
+func (r *SystemModulesProviderInfo) Decode(buf *bytes.Reader) error {
+ var err error
+
+ var val3 int32
+ err = gobtools.DecodeSimple[int32](buf, &val3)
+ if err != nil {
+ return err
+ }
+ if val3 > 0 {
+ r.HeaderJars = make([]android.Path, val3)
+ for val4 := 0; val4 < int(val3); val4++ {
+ if val6, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val6 == nil {
+ r.HeaderJars[val4] = nil
+ } else {
+ r.HeaderJars[val4] = val6.(android.Path)
+ }
+ }
+ }
+
+ if val8, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val8 == nil {
+ r.OutputDir = nil
+ } else {
+ r.OutputDir = val8.(android.Path)
+ }
+
+ var val11 int32
+ err = gobtools.DecodeSimple[int32](buf, &val11)
+ if err != nil {
+ return err
+ }
+ if val11 > 0 {
+ r.OutputDirDeps = make([]android.Path, val11)
+ for val12 := 0; val12 < int(val11); val12++ {
+ if val14, err := gobtools.DecodeInterface(buf); err != nil {
+ return err
+ } else if val14 == nil {
+ r.OutputDirDeps[val12] = nil
+ } else {
+ r.OutputDirDeps[val12] = val14.(android.Path)
+ }
+ }
+ }
+
+ if err = r.TransitiveStaticLibsHeaderJars.DecodeInterface(buf); err != nil {
+ return err
+ }
+
+ err = gobtools.DecodeSimple[bool](buf, &r.Prebuilt)
+ if err != nil {
+ return err
+ }
+
+ var val18 int32
+ err = gobtools.DecodeSimple[int32](buf, &val18)
+ if err != nil {
+ return err
+ }
+ if val18 > 0 {
+ r.Libs = make([]string, val18)
+ for val19 := 0; val19 < int(val18); val19++ {
+ err = gobtools.DecodeString(buf, &r.Libs[val19])
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return err
+}
+
+var SystemModulesProviderInfoGobRegId int16
+
+func (r SystemModulesProviderInfo) GetTypeId() int16 {
+ return SystemModulesProviderInfoGobRegId
+}
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index a60f6b82c..345090067 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -97,6 +97,13 @@ type SystemServerClasspathModule struct {
var _ android.ApexModule = (*SystemServerClasspathModule)(nil)
+type SystemServerClasspathInfo struct {
+ Contents []string
+ StandaloneContents []string
+}
+
+var SystemServerClasspathInfoProvider = blueprint.NewProvider[SystemServerClasspathInfo]()
+
func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
return android.MinApiLevel
}
@@ -139,6 +146,11 @@ func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.Mo
classpathJars = append(classpathJars, standaloneClasspathJars...)
s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
s.setPartitionInfoOfLibraries(ctx)
+
+ android.SetProvider(ctx, SystemServerClasspathInfoProvider, SystemServerClasspathInfo{
+ Contents: s.properties.Contents.GetOrDefault(ctx, nil),
+ StandaloneContents: s.properties.Standalone_contents.GetOrDefault(ctx, nil),
+ })
}
// Map of java library name to their install partition.
@@ -152,8 +164,9 @@ var LibraryNameToPartitionInfoProvider = blueprint.NewProvider[LibraryNameToPart
func (s *SystemServerClasspathModule) setPartitionInfoOfLibraries(ctx android.ModuleContext) {
libraryNameToPartition := map[string]string{}
- ctx.VisitDirectDepsWithTag(systemServerClasspathFragmentContentDepTag, func(m android.Module) {
- libraryNameToPartition[m.Name()] = m.PartitionTag(ctx.DeviceConfig())
+ ctx.VisitDirectDepsProxyWithTag(systemServerClasspathFragmentContentDepTag, func(m android.ModuleProxy) {
+ info := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
+ libraryNameToPartition[m.Name()] = info.PartitionTag
})
android.SetProvider(ctx, LibraryNameToPartitionInfoProvider, LibraryNameToPartitionInfo{
LibraryNameToPartition: libraryNameToPartition,
@@ -214,10 +227,10 @@ func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebui
// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
// they were specified using java_systemserver_libs or java_sdk_libs.
-func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType {
// If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
// property, otherwise treat if it was specified in the java_systemserver_libs property.
- if javaSdkLibrarySdkMemberType.IsInstance(child) {
+ if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) {
return javaSdkLibrarySdkMemberType
}
@@ -278,8 +291,8 @@ func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.Sd
ctx.AddVariationDependencies(nil, dependencyTag, names...)
}
-func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool {
- _, ok := module.(*SystemServerClasspathModule)
+func (s *systemServerClasspathFragmentMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool {
+ _, ok := android.OtherModuleProvider(ctx, module, SystemServerClasspathInfoProvider)
return ok
}
@@ -305,11 +318,11 @@ type systemServerClasspathFragmentSdkMemberProperties struct {
Standalone_contents []string
}
-func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
- module := variant.(*SystemServerClasspathModule)
+func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) {
+ module := android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, SystemServerClasspathInfoProvider)
- s.Contents = module.properties.Contents.GetOrDefault(ctx.SdkModuleContext(), nil)
- s.Standalone_contents = module.properties.Standalone_contents.GetOrDefault(ctx.SdkModuleContext(), nil)
+ s.Contents = module.Contents
+ s.Standalone_contents = module.StandaloneContents
}
func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
diff --git a/java/testing.go b/java/testing.go
index c5a0ef390..3989d1987 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -588,7 +588,7 @@ func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant
t.Helper()
module := ctx.ModuleForTests(t, name, variant).Module()
deps := []string{}
- ctx.VisitDirectDeps(module, func(m blueprint.Module) {
+ ctx.VisitDirectDepsProxies(module, func(m android.ModuleProxy) {
deps = append(deps, m.Name())
})
return android.SortedUniqueStrings(deps)
@@ -654,9 +654,9 @@ func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *androi
func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
t.Helper()
platformBootclasspath := ctx.ModuleForTests(t, name, variant).Module().(*platformBootclasspathModule)
- modules := []android.Module{}
- ctx.VisitDirectDeps(platformBootclasspath, func(m blueprint.Module) {
- modules = append(modules, m.(android.Module))
+ modules := []android.ModuleProxy{}
+ ctx.VisitDirectDepsProxies(platformBootclasspath, func(m android.ModuleProxy) {
+ modules = append(modules, m)
})
pairs := apexNamePairsFromModules(ctx, modules, platformBootclasspath.libraryToApex)
@@ -664,7 +664,7 @@ func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestConte
}
// apexNamePairsFromModules returns the apex:module pair for the supplied modules.
-func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module, modulesToApex map[android.Module]string) []string {
+func apexNamePairsFromModules(ctx *android.TestContext, modules []android.ModuleProxy, modulesToApex map[android.ModuleProxy]string) []string {
pairs := []string{}
for _, module := range modules {
pairs = append(pairs, apexNamePairFromModule(ctx, module, modulesToApex))
@@ -673,7 +673,7 @@ func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module
}
// ApexFragmentPairsFromModules returns the apex:fragment pair for the supplied fragments.
-func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.Module, apexNameToFragment map[string]android.Module) []string {
+func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.ModuleProxy, apexNameToFragment map[string]android.ModuleProxy) []string {
pairs := []string{}
for _, fragment := range fragments {
found := false
@@ -690,7 +690,7 @@ func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.
return pairs
}
-func apexNamePairFromModule(ctx *android.TestContext, module android.Module, modulesToApex map[android.Module]string) string {
+func apexNamePairFromModule(ctx *android.TestContext, module android.ModuleProxy, modulesToApex map[android.ModuleProxy]string) string {
name := module.Name()
apex := modulesToApex[module]
if apex == "" {