summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/Android.bp2
-rw-r--r--java/aar.go45
-rw-r--r--java/android_manifest.go9
-rw-r--r--java/androidmk.go63
-rw-r--r--java/androidmk_test.go190
-rwxr-xr-xjava/app.go202
-rw-r--r--java/app_test.go401
-rw-r--r--java/config/config.go32
-rw-r--r--java/config/makevars.go10
-rw-r--r--java/device_host_converter.go9
-rw-r--r--java/dex.go154
-rw-r--r--java/dexpreopt.go23
-rw-r--r--java/dexpreopt_bootjars.go224
-rw-r--r--java/dexpreopt_bootjars_test.go95
-rw-r--r--java/dexpreopt_config.go88
-rw-r--r--java/droiddoc.go169
-rw-r--r--java/hiddenapi.go4
-rw-r--r--java/hiddenapi_singleton.go38
-rw-r--r--java/java.go463
-rw-r--r--java/java_test.go320
-rw-r--r--java/jdeps.go1
-rw-r--r--java/kotlin.go70
-rw-r--r--java/legacy_core_platform_api_usage.go174
-rw-r--r--java/lint.go158
-rw-r--r--java/prebuilt_apis.go37
-rw-r--r--java/robolectric.go181
-rw-r--r--java/sdk.go115
-rw-r--r--java/sdk_library.go386
-rw-r--r--java/sdk_test.go81
-rw-r--r--java/testing.go68
30 files changed, 2690 insertions, 1122 deletions
diff --git a/java/Android.bp b/java/Android.bp
index 1fda7f71d..e345014ce 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -10,6 +10,7 @@ bootstrap_go_package {
"soong-dexpreopt",
"soong-genrule",
"soong-java-config",
+ "soong-python",
"soong-remoteexec",
"soong-tradefed",
],
@@ -38,6 +39,7 @@ bootstrap_go_package {
"java_resources.go",
"kotlin.go",
"lint.go",
+ "legacy_core_platform_api_usage.go",
"platform_compat_config.go",
"plugin.go",
"prebuilt_apis.go",
diff --git a/java/aar.go b/java/aar.go
index 8dd752f12..0f5e30deb 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -20,6 +20,7 @@ import (
"strings"
"android/soong/android"
+ "android/soong/dexpreopt"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -99,7 +100,7 @@ type aapt struct {
useEmbeddedNativeLibs bool
useEmbeddedDex bool
usesNonSdkApis bool
- sdkLibraries []string
+ sdkLibraries dexpreopt.LibraryPaths
hasNoCode bool
LoggingParent string
resourceFiles android.Paths
@@ -231,6 +232,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags, sdkLibraries :=
aaptLibs(ctx, sdkContext)
+ a.sdkLibraries = sdkLibraries
+
// App manifest file
manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
@@ -357,7 +360,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, transitiveStaticLibManifests android.Paths,
- staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries []string) {
+ staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries dexpreopt.LibraryPaths) {
var sharedLibs android.Paths
@@ -366,6 +369,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
sharedLibs = append(sharedLibs, sdkDep.jars...)
}
+ sdkLibraries = make(dexpreopt.LibraryPaths)
+
ctx.VisitDirectDeps(func(module android.Module) {
var exportPackage android.Path
aarDep, _ := module.(AndroidLibraryDependency)
@@ -385,7 +390,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
// (including the java_sdk_library) itself then append any implicit sdk library
// names to the list of sdk libraries to be added to the manifest.
if component, ok := module.(SdkLibraryComponentDependency); ok {
- sdkLibraries = append(sdkLibraries, component.OptionalImplicitSdkLibrary()...)
+ sdkLibraries.MaybeAddLibraryPath(ctx, component.OptionalImplicitSdkLibrary(),
+ component.DexJarBuildPath(), component.DexJarInstallPath())
}
case frameworkResTag:
@@ -393,11 +399,14 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
sharedLibs = append(sharedLibs, exportPackage)
}
case staticLibTag:
+ if dep, ok := module.(Dependency); ok {
+ sdkLibraries.AddLibraryPaths(dep.ExportedSdkLibs())
+ }
if exportPackage != nil {
transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
- sdkLibraries = append(sdkLibraries, aarDep.ExportedSdkLibs()...)
+ sdkLibraries.AddLibraryPaths(aarDep.ExportedSdkLibs())
if aarDep.ExportedAssets().Valid() {
assets = append(assets, aarDep.ExportedAssets().Path())
}
@@ -428,7 +437,6 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs)
transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests)
- sdkLibraries = android.FirstUniqueStrings(sdkLibraries)
return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags, sdkLibraries
}
@@ -465,8 +473,8 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true
- a.aapt.sdkLibraries = a.exportedSdkLibs
a.aapt.buildActions(ctx, sdkContext(a))
+ a.exportedSdkLibs = a.aapt.sdkLibraries
ctx.CheckbuildFile(a.proguardOptionsFile)
ctx.CheckbuildFile(a.exportPackage)
@@ -625,7 +633,7 @@ func (a *AARImport) JacocoReportClassesFile() android.Path {
}
func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
- if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ if !ctx.Config().AlwaysUsePrebuiltSdks() {
sdkDep := decodeSdkDep(ctx, sdkContext(a))
if sdkDep.useModule && sdkDep.frameworkResModule != "" {
ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
@@ -641,9 +649,11 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
blueprint.RuleParams{
Command: `rm -rf $outDir && mkdir -p $outDir && ` +
- `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out`,
+ `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
+ `${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
+ CommandDeps: []string{"${config.MergeZipsCmd}"},
},
- "outDir")
+ "outDir", "combinedClassesJar")
func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(a.properties.Aars) != 1 {
@@ -661,7 +671,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
extractedAARDir := android.PathForModuleOut(ctx, "aar")
- a.classpathFile = extractedAARDir.Join(ctx, "classes.jar")
+ a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
@@ -671,7 +681,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest},
Description: "unzip AAR",
Args: map[string]string{
- "outDir": extractedAARDir.String(),
+ "outDir": extractedAARDir.String(),
+ "combinedClassesJar": a.classpathFile.String(),
},
})
@@ -734,7 +745,11 @@ func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
return android.Paths{a.classpathFile}
}
-func (a *AARImport) DexJar() android.Path {
+func (a *AARImport) DexJarBuildPath() android.Path {
+ return nil
+}
+
+func (a *AARImport) DexJarInstallPath() android.Path {
return nil
}
@@ -742,7 +757,7 @@ func (a *AARImport) AidlIncludeDirs() android.Paths {
return nil
}
-func (a *AARImport) ExportedSdkLibs() []string {
+func (a *AARImport) ExportedSdkLibs() dexpreopt.LibraryPaths {
return nil
}
@@ -758,6 +773,10 @@ func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.M
return a.depIsInSameApex(ctx, dep)
}
+func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ return nil
+}
+
var _ android.PrebuiltInterface = (*Import)(nil)
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 8280cb1b1..f45ebe8d5 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -21,6 +21,7 @@ import (
"github.com/google/blueprint"
"android/soong/android"
+ "android/soong/dexpreopt"
)
var manifestFixerRule = pctx.AndroidStaticRule("manifestFixer",
@@ -52,7 +53,7 @@ var optionalUsesLibs = []string{
}
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
-func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries []string,
+func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries dexpreopt.LibraryPaths,
isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path {
var args []string
@@ -79,7 +80,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
args = append(args, "--use-embedded-dex")
}
- for _, usesLib := range sdkLibraries {
+ for usesLib, _ := range sdkLibraries {
if inList(usesLib, optionalUsesLibs) {
args = append(args, "--optional-uses-library", usesLib)
} else {
@@ -130,7 +131,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext
},
})
- return fixedManifest
+ return fixedManifest.WithoutRel()
}
func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths,
@@ -155,5 +156,5 @@ func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibM
},
})
- return mergedManifest
+ return mergedManifest.WithoutRel()
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 62f97067c..2c02e5f38 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -91,7 +91,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
} else {
mainEntries = android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFile: android.OptionalPathForPath(library.distFile),
+ DistFiles: library.distFiles,
OutputFile: android.OptionalPathForPath(library.outputFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
@@ -121,20 +121,17 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", library.jacocoReportClassesFile)
}
- entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.exportedSdkLibs...)
+ entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", android.SortedStringKeys(library.exportedSdkLibs)...)
if len(library.additionalCheckedModules) != 0 {
entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
}
- if library.proguardDictionary != nil {
- entries.SetPath("LOCAL_SOONG_PROGUARD_DICT", library.proguardDictionary)
- }
+ entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_DICT", library.dexer.proguardDictionary)
+ entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_USAGE_ZIP", library.dexer.proguardUsageZip)
entries.SetString("LOCAL_MODULE_STEM", library.Stem())
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveHTMLZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveTextZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveXMLZip)
+ entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
},
},
}
@@ -164,6 +161,7 @@ func (j *Test) AndroidMkEntries() []android.AndroidMkEntries {
if j.testConfig != nil {
entries.SetPath("LOCAL_FULL_TEST_CONFIG", j.testConfig)
}
+ androidMkWriteExtraTestConfigs(j.extraTestConfigs, entries)
androidMkWriteTestData(j.data, entries)
if !BoolDefault(j.testProperties.Auto_gen_config, true) {
entries.SetString("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", "true")
@@ -173,6 +171,12 @@ func (j *Test) AndroidMkEntries() []android.AndroidMkEntries {
return entriesList
}
+func androidMkWriteExtraTestConfigs(extraTestConfigs android.Paths, entries *android.AndroidMkEntries) {
+ if len(extraTestConfigs) > 0 {
+ entries.AddStrings("LOCAL_EXTRA_FULL_TEST_CONFIGS", extraTestConfigs.Strings()...)
+ }
+}
+
func (j *TestHelperLibrary) AndroidMkEntries() []android.AndroidMkEntries {
entriesList := j.Library.AndroidMkEntries()
entries := &entriesList[0]
@@ -198,7 +202,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))
entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
- entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion().raw)
+ entries.SetString("LOCAL_SDK_VERSION", prebuilt.makeSdkVersion())
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
},
},
@@ -334,9 +338,8 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
if app.jacocoReportClassesFile != nil {
entries.SetPath("LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR", app.jacocoReportClassesFile)
}
- if app.proguardDictionary != nil {
- entries.SetPath("LOCAL_SOONG_PROGUARD_DICT", app.proguardDictionary)
- }
+ entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_DICT", app.dexer.proguardDictionary)
+ entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_USAGE_ZIP", app.dexer.proguardUsageZip)
if app.Name() == "framework-res" {
entries.SetString("LOCAL_MODULE_PATH", "$(TARGET_OUT_JAVA_LIBRARIES)")
@@ -394,9 +397,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
}
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveHTMLZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveTextZip)
- entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveXMLZip)
+ entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -437,6 +438,7 @@ func (a *AndroidTest) AndroidMkEntries() []android.AndroidMkEntries {
if a.testConfig != nil {
entries.SetPath("LOCAL_FULL_TEST_CONFIG", a.testConfig)
}
+ androidMkWriteExtraTestConfigs(a.extraTestConfigs, entries)
androidMkWriteTestData(a.data, entries)
})
@@ -545,14 +547,12 @@ func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries {
fmt.Fprintln(w, ddoc.Name()+"-check-last-released-api:",
ddoc.checkLastReleasedApiTimestamp.String())
- if ddoc.Name() == "api-stubs-docs" || ddoc.Name() == "system-api-stubs-docs" {
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- ddoc.checkLastReleasedApiTimestamp.String())
+ fmt.Fprintln(w, ".PHONY: checkapi")
+ fmt.Fprintln(w, "checkapi:",
+ ddoc.checkLastReleasedApiTimestamp.String())
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
+ fmt.Fprintln(w, ".PHONY: droidcore")
+ fmt.Fprintln(w, "droidcore: checkapi")
}
},
},
@@ -565,15 +565,21 @@ func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
// are created in make if only the api txt file is being generated. This is
// needed because an invalid output file would prevent the make entries from
// being written.
+ //
+ // Note that dstubs.apiFile can be also be nil if WITHOUT_CHECKS_API is true.
// TODO(b/146727827): Revert when we do not need to generate stubs and API separately.
- distFile := android.OptionalPathForPath(dstubs.apiFile)
+
+ var distFiles android.TaggedDistFiles
+ if dstubs.apiFile != nil {
+ distFiles = android.MakeDefaultDistFiles(dstubs.apiFile)
+ }
outputFile := android.OptionalPathForPath(dstubs.stubsSrcJar)
if !outputFile.Valid() {
- outputFile = distFile
+ outputFile = android.OptionalPathForPath(dstubs.apiFile)
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFile: distFile,
+ DistFiles: distFiles,
OutputFile: outputFile,
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
@@ -669,6 +675,11 @@ func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
}
func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries {
+ if !a.IsForPlatform() {
+ // The non-platform variant is placed inside APEX. No reason to
+ // make it available to Make.
+ return nil
+ }
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "APPS",
OutputFile: android.OptionalPathForPath(a.outputFile),
@@ -729,7 +740,7 @@ func (apkSet *AndroidAppSet) AndroidMkEntries() []android.AndroidMkEntries {
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(entries *android.AndroidMkEntries) {
entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", apkSet.Privileged())
- entries.SetString("LOCAL_APK_SET_MASTER_FILE", apkSet.masterFile)
+ entries.SetString("LOCAL_APK_SET_INSTALL_FILE", apkSet.InstallFile())
entries.SetPath("LOCAL_APKCERTS_FILE", apkSet.apkcertsFile)
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", apkSet.properties.Overrides...)
},
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 7daa6244f..075b7aa6f 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -156,16 +156,190 @@ func TestDistWithTag(t *testing.T) {
}
`)
- without_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_without_tag", "android_common").Module())
- with_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_with_tag", "android_common").Module())
+ withoutTagEntries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_without_tag", "android_common").Module())
+ withTagEntries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_with_tag", "android_common").Module())
- if len(without_tag_entries) != 2 || len(with_tag_entries) != 2 {
- t.Errorf("two mk entries per module expected, got %d and %d", len(without_tag_entries), len(with_tag_entries))
+ if len(withoutTagEntries) != 2 || len(withTagEntries) != 2 {
+ t.Errorf("two mk entries per module expected, got %d and %d", len(withoutTagEntries), len(withTagEntries))
}
- if !with_tag_entries[0].DistFile.Valid() || !strings.Contains(with_tag_entries[0].DistFile.String(), "/javac/foo_with_tag.jar") {
- t.Errorf("expected classes.jar DistFile, got %v", with_tag_entries[0].DistFile)
+ if len(withTagEntries[0].DistFiles[".jar"]) != 1 ||
+ !strings.Contains(withTagEntries[0].DistFiles[".jar"][0].String(), "/javac/foo_with_tag.jar") {
+ t.Errorf("expected DistFiles to contain classes.jar, got %v", withTagEntries[0].DistFiles)
}
- if without_tag_entries[0].DistFile.Valid() {
- t.Errorf("did not expect explicit DistFile, got %v", without_tag_entries[0].DistFile)
+ if len(withoutTagEntries[0].DistFiles[".jar"]) > 0 {
+ t.Errorf("did not expect explicit DistFile for .jar tag, got %v", withoutTagEntries[0].DistFiles[".jar"])
+ }
+}
+
+func TestDistWithDest(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["my_goal"],
+ dest: "my/custom/dest/dir",
+ },
+ }
+ `)
+
+ module := ctx.ModuleForTests("foo", "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)
+ if len(entries) != 2 {
+ t.Errorf("Expected 2 AndroidMk entries, got %d", len(entries))
+ }
+
+ distStrings := entries[0].GetDistForGoals(module)
+
+ if len(distStrings) != 2 {
+ t.Errorf("Expected 2 entries for dist: PHONY and dist-for-goals, but got %q", distStrings)
+ }
+
+ if distStrings[0] != ".PHONY: my_goal\n" {
+ t.Errorf("Expected .PHONY entry to declare my_goal, but got: %s", distStrings[0])
+ }
+
+ if !strings.Contains(distStrings[1], "$(call dist-for-goals,my_goal") ||
+ !strings.Contains(distStrings[1], ".intermediates/foo/android_common/dex/foo.jar:my/custom/dest/dir") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain my_goal and new dest dir, but got: %s", distStrings[1])
+ }
+}
+
+func TestDistsWithAllProperties(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["baz"],
+ },
+ dists: [
+ {
+ targets: ["bar"],
+ tag: ".jar",
+ dest: "bar.jar",
+ dir: "bar/dir",
+ suffix: ".qux",
+ },
+ ]
+ }
+ `)
+
+ module := ctx.ModuleForTests("foo", "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)
+ if len(entries) != 2 {
+ t.Errorf("Expected 2 AndroidMk entries, got %d", len(entries))
+ }
+
+ distStrings := entries[0].GetDistForGoals(module)
+
+ if len(distStrings) != 4 {
+ t.Errorf("Expected 4 entries for dist: PHONY and dist-for-goals, but got %d", len(distStrings))
+ }
+
+ if distStrings[0] != ".PHONY: bar\n" {
+ t.Errorf("Expected .PHONY entry to declare bar, but got: %s", distStrings[0])
+ }
+
+ if !strings.Contains(distStrings[1], "$(call dist-for-goals,bar") ||
+ !strings.Contains(
+ distStrings[1],
+ ".intermediates/foo/android_common/javac/foo.jar:bar/dir/bar.qux.jar") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain bar and new dest dir, but got: %s", distStrings[1])
+ }
+
+ if distStrings[2] != ".PHONY: baz\n" {
+ t.Errorf("Expected .PHONY entry to declare baz, but got: %s", distStrings[2])
+ }
+
+ if !strings.Contains(distStrings[3], "$(call dist-for-goals,baz") ||
+ !strings.Contains(distStrings[3], ".intermediates/foo/android_common/dex/foo.jar:foo.jar") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain my_other_goal and new dest dir, but got: %s",
+ distStrings[3])
+ }
+}
+
+func TestDistsWithTag(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo_without_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dists: [
+ {
+ targets: ["hi"],
+ },
+ ],
+ }
+ java_library {
+ name: "foo_with_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dists: [
+ {
+ targets: ["hi"],
+ tag: ".jar",
+ },
+ ],
+ }
+ `)
+
+ moduleWithoutTag := ctx.ModuleForTests("foo_without_tag", "android_common").Module()
+ moduleWithTag := ctx.ModuleForTests("foo_with_tag", "android_common").Module()
+
+ withoutTagEntries := android.AndroidMkEntriesForTest(t, config, "", moduleWithoutTag)
+ withTagEntries := android.AndroidMkEntriesForTest(t, config, "", moduleWithTag)
+
+ if len(withoutTagEntries) != 2 || len(withTagEntries) != 2 {
+ t.Errorf("two mk entries per module expected, got %d and %d", len(withoutTagEntries), len(withTagEntries))
+ }
+
+ distFilesWithoutTag := withoutTagEntries[0].DistFiles
+ distFilesWithTag := withTagEntries[0].DistFiles
+
+ if len(distFilesWithTag[".jar"]) != 1 ||
+ !strings.Contains(distFilesWithTag[".jar"][0].String(), "/javac/foo_with_tag.jar") {
+ t.Errorf("expected foo_with_tag's .jar-tagged DistFiles to contain classes.jar, got %v", distFilesWithTag[".jar"])
+ }
+ if len(distFilesWithoutTag[".jar"]) > 0 {
+ t.Errorf("did not expect foo_without_tag's .jar-tagged DistFiles to contain files, but got %v", distFilesWithoutTag[".jar"])
+ }
+}
+
+func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_sdk_library {
+ name: "foo-shared_library",
+ srcs: ["a.java"],
+ }
+ java_sdk_library {
+ name: "foo-no_shared_library",
+ srcs: ["a.java"],
+ shared_library: false,
+ }
+ `)
+
+ // Verify the existence of internal modules
+ ctx.ModuleForTests("foo-shared_library.xml", "android_common")
+
+ testCases := []struct {
+ moduleName string
+ expected []string
+ }{
+ {"foo-shared_library", []string{"foo-shared_library.xml"}},
+ {"foo-no_shared_library", nil},
+ }
+ for _, tc := range testCases {
+ mod := ctx.ModuleForTests(tc.moduleName, "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0]
+ actual := entries.EntryMap["LOCAL_REQUIRED_MODULES"]
+ if !reflect.DeepEqual(tc.expected, actual) {
+ t.Errorf("Unexpected required modules - expected: %q, actual: %q", tc.expected, actual)
+ }
}
}
diff --git a/java/app.go b/java/app.go
index e75d8749f..900f6a6d7 100755
--- a/java/app.go
+++ b/java/app.go
@@ -28,6 +28,7 @@ import (
"android/soong/android"
"android/soong/cc"
+ "android/soong/dexpreopt"
"android/soong/tradefed"
)
@@ -77,7 +78,7 @@ type AndroidAppSet struct {
properties AndroidAppSetProperties
packedOutput android.WritablePath
- masterFile string
+ installFile string
apkcertsFile android.ModuleOutPath
}
@@ -101,8 +102,8 @@ func (as *AndroidAppSet) OutputFile() android.Path {
return as.packedOutput
}
-func (as *AndroidAppSet) MasterFile() string {
- return as.masterFile
+func (as *AndroidAppSet) InstallFile() string {
+ return as.installFile
}
func (as *AndroidAppSet) APKCertsFile() android.Path {
@@ -135,10 +136,10 @@ func SupportedAbis(ctx android.ModuleContext) []string {
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
as.apkcertsFile = android.PathForModuleOut(ctx, "apkcerts.txt")
- // We are assuming here that the master file in the APK
+ // We are assuming here that the install file in the APK
// set has `.apk` suffix. If it doesn't the build will fail.
// APK sets containing APEX files are handled elsewhere.
- as.masterFile = as.BaseModuleName() + ".apk"
+ as.installFile = as.BaseModuleName() + ".apk"
screenDensities := "all"
if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
screenDensities = strings.ToUpper(strings.Join(dpis, ","))
@@ -166,7 +167,7 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
// android_app_set extracts a set of APKs based on the target device
// configuration and installs this set as "split APKs".
-// The extracted set always contains 'master' APK whose name is
+// The extracted set always contains an APK whose name is
// _module_name_.apk and every split APK matching target device.
// The extraction of the density-specific splits depends on
// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
@@ -267,6 +268,9 @@ type overridableAppProperties struct {
// the logging parent of this app.
Logging_parent *string
+
+ // Whether to rename the package in resources to the override name rather than the base name. Defaults to true.
+ Rename_resources_package *bool
}
// runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay
@@ -431,8 +435,10 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
if String(a.deviceProperties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.")
}
+
if minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx); err == nil {
a.checkJniLibsSdkVersion(ctx, minSdkVersion)
+ android.CheckMinSdkVersion(a, ctx, int(minSdkVersion))
} else {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
}
@@ -504,10 +510,23 @@ func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool {
!a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs
}
+func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string {
+ aaptFlags := []string{"--rename-manifest-package " + packageName}
+ if renameResourcesPackage {
+ // Required to rename the package name in the resources table.
+ aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName)
+ }
+ return aaptFlags
+}
+
func (a *AndroidApp) OverriddenManifestPackageName() string {
return a.overriddenManifestPackageName
}
+func (a *AndroidApp) renameResourcesPackage() bool {
+ return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
+}
+
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis)
@@ -540,7 +559,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
if !overridden {
manifestPackageName = *a.overridableAppProperties.Package_name
}
- aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
+ aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...)
a.overriddenManifestPackageName = manifestPackageName
}
@@ -583,18 +602,20 @@ func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext, sdkLibs dexpreopt.LibraryPaths) android.Path {
a.dexpreopter.installPath = a.installPath(ctx)
- if a.deviceProperties.Uncompress_dex == nil {
+ if a.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
- a.deviceProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
+ a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
}
- a.dexpreopter.uncompressedDex = *a.deviceProperties.Uncompress_dex
+ a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
+ a.dexpreopter.libraryPaths.AddLibraryPaths(sdkLibs)
a.dexpreopter.manifestFile = a.mergedManifestFile
+ a.exportedSdkLibs = make(dexpreopt.LibraryPaths)
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
@@ -663,16 +684,20 @@ func (a *AndroidApp) noticeBuildActions(ctx android.ModuleContext) {
return false
}
- path := child.(android.Module).NoticeFile()
- if path.Valid() {
- noticePathSet[path.Path()] = true
+ paths := child.(android.Module).NoticeFiles()
+ if len(paths) > 0 {
+ for _, path := range paths {
+ noticePathSet[path] = true
+ }
}
return true
})
// If the app has one, add it too.
- if a.NoticeFile().Valid() {
- noticePathSet[a.NoticeFile().Path()] = true
+ if len(a.NoticeFiles()) > 0 {
+ for _, path := range a.NoticeFiles() {
+ noticePathSet[path] = true
+ }
}
if len(noticePathSet) == 0 {
@@ -759,6 +784,15 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
+ // The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
+ a.usesLibrary.freezeEnforceUsesLibraries()
+
+ // Add implicit SDK libraries to <uses-library> list.
+ for _, usesLib := range android.SortedStringKeys(a.aapt.sdkLibraries) {
+ a.usesLibrary.addLib(usesLib, inList(usesLib, optionalUsesLibs))
+ }
+
+ // Check that the <uses-library> list is coherent with the manifest.
if a.usesLibrary.enforceUsesLibraries() {
manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
apkDeps = append(apkDeps, manifestCheckFile)
@@ -769,9 +803,9 @@ 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().UnbundledBuild()
+ a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile := a.dexBuildActions(ctx)
+ dexJarFile := a.dexBuildActions(ctx, a.aapt.sdkLibraries)
jniLibs, certificateDeps := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, ctx)
@@ -852,7 +886,7 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
- if IsJniDepTag(tag) || tag == cc.SharedDepTag {
+ if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
if dep, ok := module.(*cc.Module); ok {
if dep.IsNdk() || dep.IsStubs() {
return false
@@ -902,13 +936,13 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
return jniLibs, certificates
}
-func (a *AndroidApp) walkPayloadDeps(ctx android.ModuleContext,
- do func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool)) {
-
+func (a *AndroidApp) WalkPayloadDeps(ctx android.ModuleContext, do android.PayloadDepsCallback) {
ctx.WalkDeps(func(child, parent android.Module) bool {
isExternal := !a.DepIsInSameApex(ctx, child)
if am, ok := child.(android.ApexModule); ok {
- do(ctx, parent, am, isExternal)
+ if !do(ctx, parent, am, isExternal) {
+ return false
+ }
}
return !isExternal
})
@@ -920,7 +954,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
}
depsInfo := android.DepNameToDepInfoMap{}
- a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
+ a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
depName := to.Name()
if info, exist := depsInfo[depName]; exist {
info.From = append(info.From, from.Name())
@@ -940,6 +974,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) {
MinSdkVersion: toMinSdkVersion,
}
}
+ return true
})
a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(), depsInfo)
@@ -969,6 +1004,8 @@ func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case ".aapt.srcjar":
return []android.Path{a.aaptSrcJar}, nil
+ case ".export-package.apk":
+ return []android.Path{a.exportPackage}, nil
}
return a.Library.OutputFiles(tag)
}
@@ -993,14 +1030,16 @@ func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
a.appProperties.IsCoverageVariant = coverage
}
+func (a *AndroidApp) EnableCoverageIfNeeded() {}
+
var _ cc.Coverage = (*AndroidApp)(nil)
// android_app compiles sources and Android resources into an Android application package `.apk` file.
func AndroidAppFactory() android.Module {
module := &AndroidApp{}
- module.Module.deviceProperties.Optimize.EnabledByDefault = true
- module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
+ module.Module.dexProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
module.Module.properties.Instrument = true
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -1012,10 +1051,6 @@ func AndroidAppFactory() android.Module {
&module.overridableAppProperties,
&module.usesLibrary.usesLibraryProperties)
- module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
- return class == android.Device && ctx.Config().DevicePrefer32BitApps()
- })
-
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.appProperties.Overrides)
@@ -1025,6 +1060,7 @@ func AndroidAppFactory() android.Module {
}
type appTestProperties struct {
+ // The name of the android_app module that the tests will run against.
Instrumentation_for *string
// if specified, the instrumentation target package name in the manifest is overwritten by it.
@@ -1038,8 +1074,9 @@ type AndroidTest struct {
testProperties testProperties
- testConfig android.Path
- data android.Paths
+ testConfig android.Path
+ extraTestConfigs android.Paths
+ data android.Paths
}
func (a *AndroidTest) InstallInTestcases() bool {
@@ -1067,6 +1104,7 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config, configs)
a.testConfig = a.FixTestConfig(ctx, testConfig)
+ a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
@@ -1117,7 +1155,7 @@ func (a *AndroidTest) OverridablePropertiesDepsMutator(ctx android.BottomUpMutat
func AndroidTestFactory() android.Module {
module := &AndroidTest{}
- module.Module.deviceProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.EnabledByDefault = true
module.Module.properties.Instrument = true
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -1168,7 +1206,7 @@ func (a *AndroidTestHelperApp) InstallInTestcases() bool {
func AndroidTestHelperAppFactory() android.Module {
module := &AndroidTestHelperApp{}
- module.Module.deviceProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.EnabledByDefault = true
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
@@ -1285,6 +1323,7 @@ func OverrideRuntimeResourceOverlayModuleFactory() android.Module {
type AndroidAppImport struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
prebuilt android.Prebuilt
properties AndroidAppImportProperties
@@ -1535,7 +1574,9 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
// TODO: Optionally compress the output apk.
- a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
+ if a.IsForPlatform() {
+ a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
+ }
// TODO: androidmk converter jni libs
}
@@ -1586,6 +1627,13 @@ func (a *AndroidAppImport) Privileged() bool {
return Bool(a.properties.Privileged)
}
+func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
+ // android_app_import might have extra dependencies via uses_libs property.
+ // Don't track the dependency as we don't automatically add those libraries
+ // to the classpath. It should be explicitly added to java_libs property of APEX
+ return false
+}
+
func (a *AndroidAppImport) sdkVersion() sdkSpec {
return sdkSpecFrom("")
}
@@ -1594,6 +1642,11 @@ func (a *AndroidAppImport) minSdkVersion() sdkSpec {
return sdkSpecFrom("")
}
+func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ // Do not check for prebuilts against the min_sdk_version of enclosing APEX
+ return nil
+}
+
func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
props := reflect.TypeOf((*AndroidAppImportProperties)(nil))
@@ -1640,6 +1693,7 @@ func AndroidAppImportFactory() android.Module {
module.processVariants(ctx)
})
+ android.InitApexModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
@@ -1690,6 +1744,7 @@ func AndroidTestImportFactory() android.Module {
module.dexpreopter.isTest = true
+ android.InitApexModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
@@ -1746,6 +1801,15 @@ type RuntimeResourceOverlayProperties struct {
Overrides []string
}
+// RuntimeResourceOverlayModule interface is used by the apex package to gather information from
+// a RuntimeResourceOverlay module.
+type RuntimeResourceOverlayModule interface {
+ android.Module
+ OutputFile() android.Path
+ Certificate() Certificate
+ Theme() string
+}
+
func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
sdkDep := decodeSdkDep(ctx, sdkContext(r))
if sdkDep.hasFrameworkLibs() {
@@ -1773,7 +1837,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC
if !overridden {
manifestPackageName = *r.overridableProperties.Package_name
}
- aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName)
+ aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...)
}
if r.overridableProperties.Target_package_name != nil {
aaptLinkFlags = append(aaptLinkFlags,
@@ -1816,6 +1880,18 @@ func (r *RuntimeResourceOverlay) targetSdkVersion() sdkSpec {
return r.sdkVersion()
}
+func (r *RuntimeResourceOverlay) Certificate() Certificate {
+ return r.certificate
+}
+
+func (r *RuntimeResourceOverlay) OutputFile() android.Path {
+ return r.outputFile
+}
+
+func (r *RuntimeResourceOverlay) Theme() string {
+ return String(r.properties.Theme)
+}
+
// runtime_resource_overlay generates a resource-only apk file that can overlay application and
// system resources at run time.
func RuntimeResourceOverlayFactory() android.Module {
@@ -1852,6 +1928,16 @@ type usesLibrary struct {
usesLibraryProperties UsesLibraryProperties
}
+func (u *usesLibrary) addLib(lib string, optional bool) {
+ if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
+ if optional {
+ u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
+ } else {
+ u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
+ }
+ }
+}
+
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
if !ctx.Config().UnbundledBuild() {
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
@@ -1860,13 +1946,13 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs
// creating a cyclic dependency:
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
if hasFrameworkLibs {
- // dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
- // to pass them to dex2oat. Add them as a dependency so we can determine the path to the dex jar of each
- // library to dexpreopt.
+ // Dexpreopt needs paths to the dex jars of these libraries in order to construct
+ // class loader context for dex2oat. Add them as a dependency with a special tag.
ctx.AddVariationDependencies(nil, usesLibTag,
"org.apache.http.legacy",
"android.hidl.base-V1.0-java",
"android.hidl.manager-V1.0-java")
+ ctx.AddVariationDependencies(nil, usesLibTag, optionalUsesLibs...)
}
}
}
@@ -1878,24 +1964,36 @@ func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []s
return optionalUsesLibs
}
-// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
-func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
- usesLibPaths := make(map[string]android.Path)
+// usesLibraryPaths returns a map of module names of shared library dependencies to the paths
+// to their dex jars on host and on device.
+func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) dexpreopt.LibraryPaths {
+ usesLibPaths := make(dexpreopt.LibraryPaths)
if !ctx.Config().UnbundledBuild() {
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
+ dep := ctx.OtherModuleName(m)
if lib, ok := m.(Dependency); ok {
- if dexJar := lib.DexJar(); dexJar != nil {
- usesLibPaths[ctx.OtherModuleName(m)] = dexJar
+ buildPath := lib.DexJarBuildPath()
+ if buildPath == nil {
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must"+
+ " produce a dex jar, does it have installable: true?", dep)
+ return
+ }
+
+ var devicePath string
+ installPath := lib.DexJarInstallPath()
+ if installPath == nil {
+ devicePath = filepath.Join("/system/framework", dep+".jar")
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
- ctx.OtherModuleName(m))
+ devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath))
}
+
+ usesLibPaths[dep] = &dexpreopt.LibraryPath{buildPath, devicePath}
} else if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
+ ctx.AddMissingDependencies([]string{dep})
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
- ctx.OtherModuleName(m))
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be "+
+ "a java library", dep)
}
})
}
@@ -1912,6 +2010,12 @@ func (u *usesLibrary) enforceUsesLibraries() bool {
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs)
}
+// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
+func (u *usesLibrary) freezeEnforceUsesLibraries() {
+ enforce := u.enforceUsesLibraries()
+ u.usesLibraryProperties.Enforce_uses_libs = &enforce
+}
+
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest.
func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
diff --git a/java/app_test.go b/java/app_test.go
index 8ef315206..536797119 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -161,11 +161,11 @@ func TestAndroidAppSet(t *testing.T) {
t.Errorf("wrong partition value: '%s', expected 'system'", s)
}
mkEntries := android.AndroidMkEntriesForTest(t, config, "", module.Module())[0]
- actualMaster := mkEntries.EntryMap["LOCAL_APK_SET_MASTER_FILE"]
- expectedMaster := []string{"foo.apk"}
- if !reflect.DeepEqual(actualMaster, expectedMaster) {
- t.Errorf("Unexpected LOCAL_APK_SET_MASTER_FILE value: '%s', expected: '%s',",
- actualMaster, expectedMaster)
+ actualInstallFile := mkEntries.EntryMap["LOCAL_APK_SET_INSTALL_FILE"]
+ expectedInstallFile := []string{"foo.apk"}
+ if !reflect.DeepEqual(actualInstallFile, expectedInstallFile) {
+ t.Errorf("Unexpected LOCAL_APK_SET_INSTALL_FILE value: '%s', expected: '%s',",
+ actualInstallFile, expectedInstallFile)
}
}
@@ -478,6 +478,24 @@ func TestUpdatableApps(t *testing.T) {
}
}
+func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
+ testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ updatable: true,
+ sdk_version: "current",
+ min_sdk_version: "29",
+ static_libs: ["bar"],
+ }
+
+ java_library {
+ name: "bar",
+ sdk_version: "current",
+ }
+ `)
+}
+
func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
@@ -515,16 +533,6 @@ func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
system_shared_libs: [],
sdk_version: "29",
}
-
- ndk_prebuilt_object {
- name: "ndk_crtbegin_so.29",
- sdk_version: "29",
- }
-
- ndk_prebuilt_object {
- name: "ndk_crtend_so.29",
- sdk_version: "29",
- }
`
fs := map[string][]byte{
"prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
@@ -537,16 +545,28 @@ func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
var crtbeginFound, crtendFound bool
+ expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
+ "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ expectedCrtEnd := ctx.ModuleForTests("crtend_so",
+ "android_arm64_armv8-a_sdk_29").Rule("partialLd").Output
+ implicits := []string{}
for _, input := range inputs {
- switch input.String() {
- case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o":
+ implicits = append(implicits, input.String())
+ if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
crtbeginFound = true
- case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o":
+ } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
crtendFound = true
}
}
- if !crtbeginFound || !crtendFound {
- t.Error("should link with ndk_crtbegin_so.29 and ndk_crtend_so.29")
+ if !crtbeginFound {
+ t.Error(fmt.Sprintf(
+ "expected implicit with suffix %q, have the following implicits:\n%s",
+ expectedCrtBegin, strings.Join(implicits, "\n")))
+ }
+ if !crtendFound {
+ t.Error(fmt.Sprintf(
+ "expected implicit with suffix %q, have the following implicits:\n%s",
+ expectedCrtEnd, strings.Join(implicits, "\n")))
}
}
@@ -1020,6 +1040,35 @@ func TestAndroidResources(t *testing.T) {
}
}
+func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) {
+ ctx := testContext()
+
+ run(t, ctx, config)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ link := foo.Output("package-res.apk")
+ linkFlags := strings.Split(link.Args["flags"], " ")
+ min := android.IndexList("--min-sdk-version", linkFlags)
+ target := android.IndexList("--target-sdk-version", linkFlags)
+
+ if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
+ t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
+ }
+
+ gotMinSdkVersion := linkFlags[min+1]
+ gotTargetSdkVersion := linkFlags[target+1]
+
+ if gotMinSdkVersion != expectedSdkVersion {
+ t.Errorf("incorrect --min-sdk-version, expected %q got %q",
+ expectedSdkVersion, gotMinSdkVersion)
+ }
+
+ if gotTargetSdkVersion != expectedSdkVersion {
+ t.Errorf("incorrect --target-sdk-version, expected %q got %q",
+ expectedSdkVersion, gotTargetSdkVersion)
+ }
+}
+
func TestAppSdkVersion(t *testing.T) {
testCases := []struct {
name string
@@ -1089,34 +1138,81 @@ func TestAppSdkVersion(t *testing.T) {
config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
+ checkSdkVersion(t, config, test.expectedMinSdkVersion)
- ctx := testContext()
-
- run(t, ctx, config)
-
- foo := ctx.ModuleForTests("foo", "android_common")
- link := foo.Output("package-res.apk")
- linkFlags := strings.Split(link.Args["flags"], " ")
- min := android.IndexList("--min-sdk-version", linkFlags)
- target := android.IndexList("--target-sdk-version", linkFlags)
-
- if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
- t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
- }
-
- gotMinSdkVersion := linkFlags[min+1]
- gotTargetSdkVersion := linkFlags[target+1]
+ })
+ }
+ }
+}
- if gotMinSdkVersion != test.expectedMinSdkVersion {
- t.Errorf("incorrect --min-sdk-version, expected %q got %q",
- test.expectedMinSdkVersion, gotMinSdkVersion)
- }
+func TestVendorAppSdkVersion(t *testing.T) {
+ testCases := []struct {
+ name string
+ sdkVersion string
+ platformSdkInt int
+ platformSdkCodename string
+ platformSdkFinal bool
+ deviceCurrentApiLevelForVendorModules string
+ expectedMinSdkVersion string
+ }{
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "REL",
+ platformSdkFinal: true,
+ deviceCurrentApiLevelForVendorModules: "29",
+ expectedMinSdkVersion: "29",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "REL",
+ platformSdkFinal: true,
+ deviceCurrentApiLevelForVendorModules: "28",
+ expectedMinSdkVersion: "28",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "Q",
+ platformSdkFinal: false,
+ deviceCurrentApiLevelForVendorModules: "current",
+ expectedMinSdkVersion: "Q",
+ },
+ {
+ name: "current final SDK",
+ sdkVersion: "current",
+ platformSdkInt: 29,
+ platformSdkCodename: "Q",
+ platformSdkFinal: false,
+ deviceCurrentApiLevelForVendorModules: "28",
+ expectedMinSdkVersion: "28",
+ },
+ }
- if gotTargetSdkVersion != test.expectedMinSdkVersion {
- t.Errorf("incorrect --target-sdk-version, expected %q got %q",
- test.expectedMinSdkVersion, gotTargetSdkVersion)
- }
- })
+ for _, moduleType := range []string{"android_app", "android_library"} {
+ for _, sdkKind := range []string{"", "system_"} {
+ for _, test := range testCases {
+ t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ bp := fmt.Sprintf(`%s {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "%s%s",
+ vendor: true,
+ }`, moduleType, sdkKind, test.sdkVersion)
+
+ config := testAppConfig(nil, bp, nil)
+ config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
+ config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
+ config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
+ config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
+ config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"}
+ checkSdkVersion(t, config, test.expectedMinSdkVersion)
+ })
+ }
}
}
}
@@ -1743,52 +1839,125 @@ func TestOverrideAndroidApp(t *testing.T) {
base: "foo",
package_name: "org.dandroid.bp",
}
+
+ override_android_app {
+ name: "baz_no_rename_resources",
+ base: "foo",
+ package_name: "org.dandroid.bp",
+ rename_resources_package: false,
+ }
+
+ android_app {
+ name: "foo_no_rename_resources",
+ srcs: ["a.java"],
+ certificate: "expiredkey",
+ overrides: ["qux"],
+ rename_resources_package: false,
+ sdk_version: "current",
+ }
+
+ override_android_app {
+ name: "baz_base_no_rename_resources",
+ base: "foo_no_rename_resources",
+ package_name: "org.dandroid.bp",
+ }
+
+ override_android_app {
+ name: "baz_override_base_rename_resources",
+ base: "foo_no_rename_resources",
+ package_name: "org.dandroid.bp",
+ rename_resources_package: true,
+ }
`)
expectedVariants := []struct {
- moduleName string
- variantName string
- apkName string
- apkPath string
- certFlag string
- lineageFlag string
- overrides []string
- aaptFlag string
- logging_parent string
+ name string
+ moduleName string
+ variantName string
+ apkName string
+ apkPath string
+ certFlag string
+ lineageFlag string
+ overrides []string
+ packageFlag string
+ renameResources bool
+ logging_parent string
}{
{
- moduleName: "foo",
- variantName: "android_common",
- apkPath: "/target/product/test_device/system/app/foo/foo.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- lineageFlag: "",
- overrides: []string{"qux"},
- aaptFlag: "",
- logging_parent: "",
- },
- {
- moduleName: "bar",
- variantName: "android_common_bar",
- apkPath: "/target/product/test_device/system/app/bar/bar.apk",
- certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
- lineageFlag: "--lineage lineage.bin",
- overrides: []string{"qux", "foo"},
- aaptFlag: "",
- logging_parent: "bah",
- },
- {
- moduleName: "baz",
- variantName: "android_common_baz",
- apkPath: "/target/product/test_device/system/app/baz/baz.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- lineageFlag: "",
- overrides: []string{"qux", "foo"},
- aaptFlag: "--rename-manifest-package org.dandroid.bp",
- logging_parent: "",
+ name: "foo",
+ moduleName: "foo",
+ variantName: "android_common",
+ apkPath: "/target/product/test_device/system/app/foo/foo.apk",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
+ overrides: []string{"qux"},
+ packageFlag: "",
+ renameResources: false,
+ logging_parent: "",
+ },
+ {
+ name: "foo",
+ moduleName: "bar",
+ variantName: "android_common_bar",
+ apkPath: "/target/product/test_device/system/app/bar/bar.apk",
+ certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ lineageFlag: "--lineage lineage.bin",
+ overrides: []string{"qux", "foo"},
+ packageFlag: "",
+ renameResources: false,
+ logging_parent: "bah",
+ },
+ {
+ name: "foo",
+ moduleName: "baz",
+ variantName: "android_common_baz",
+ apkPath: "/target/product/test_device/system/app/baz/baz.apk",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
+ overrides: []string{"qux", "foo"},
+ packageFlag: "org.dandroid.bp",
+ renameResources: true,
+ logging_parent: "",
+ },
+ {
+ name: "foo",
+ moduleName: "baz_no_rename_resources",
+ variantName: "android_common_baz_no_rename_resources",
+ apkPath: "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
+ overrides: []string{"qux", "foo"},
+ packageFlag: "org.dandroid.bp",
+ renameResources: false,
+ logging_parent: "",
+ },
+ {
+ name: "foo_no_rename_resources",
+ moduleName: "baz_base_no_rename_resources",
+ variantName: "android_common_baz_base_no_rename_resources",
+ apkPath: "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
+ overrides: []string{"qux", "foo_no_rename_resources"},
+ packageFlag: "org.dandroid.bp",
+ renameResources: false,
+ logging_parent: "",
+ },
+ {
+ name: "foo_no_rename_resources",
+ moduleName: "baz_override_base_rename_resources",
+ variantName: "android_common_baz_override_base_rename_resources",
+ apkPath: "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
+ certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ lineageFlag: "",
+ overrides: []string{"qux", "foo_no_rename_resources"},
+ packageFlag: "org.dandroid.bp",
+ renameResources: true,
+ logging_parent: "",
},
}
for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo", expected.variantName)
+ variant := ctx.ModuleForTests(expected.name, expected.variantName)
// Check the final apk name
outputs := variant.AllOutputs()
@@ -1834,9 +2003,12 @@ func TestOverrideAndroidApp(t *testing.T) {
// Check the package renaming flag, if exists.
res := variant.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
- if !strings.Contains(aapt2Flags, expected.aaptFlag) {
- t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags)
+ checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+ expectedPackage := expected.packageFlag
+ if !expected.renameResources {
+ expectedPackage = ""
}
+ checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
}
}
@@ -1973,6 +2145,7 @@ func TestOverrideAndroidTest(t *testing.T) {
res := variant.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+ checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
}
}
@@ -2568,10 +2741,37 @@ func TestUsesLibraries(t *testing.T) {
sdk_version: "current",
}
+ java_sdk_library {
+ name: "runtime-library",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "static-runtime-helper",
+ srcs: ["a.java"],
+ libs: ["runtime-library"],
+ sdk_version: "current",
+ }
+
android_app {
name: "app",
srcs: ["a.java"],
+ libs: ["qux", "quuz"],
+ static_libs: ["static-runtime-helper"],
+ uses_libs: ["foo"],
+ sdk_version: "current",
+ optional_uses_libs: [
+ "bar",
+ "baz",
+ ],
+ }
+
+ android_app {
+ name: "app_with_stub_deps",
+ srcs: ["a.java"],
libs: ["qux", "quuz.stubs"],
+ static_libs: ["static-runtime-helper"],
uses_libs: ["foo"],
sdk_version: "current",
optional_uses_libs: [
@@ -2600,15 +2800,15 @@ func TestUsesLibraries(t *testing.T) {
run(t, ctx, config)
app := ctx.ModuleForTests("app", "android_common")
+ appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common")
prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
manifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- if w := "--uses-library qux"; !strings.Contains(manifestFixerArgs, w) {
- t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
- }
- if w := "--uses-library quuz"; !strings.Contains(manifestFixerArgs, w) {
- t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
+ for _, w := range []string{"qux", "quuz", "runtime-library"} {
+ if !strings.Contains(manifestFixerArgs, "--uses-library "+w) {
+ t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
+ }
}
// Test that all libraries are verified
@@ -2631,16 +2831,25 @@ func TestUsesLibraries(t *testing.T) {
t.Errorf("wanted %q in %q", w, cmd)
}
- // Test that only present libraries are preopted
+ // Test that all present libraries are preopted, including implicit SDK dependencies
cmd = app.Rule("dexpreopt").RuleParams.Command
-
- if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
+ w := `--target-classpath-for-sdk any` +
+ ` /system/framework/foo.jar` +
+ `:/system/framework/quuz.jar` +
+ `:/system/framework/qux.jar` +
+ `:/system/framework/runtime-library.jar` +
+ `:/system/framework/bar.jar`
+ if !strings.Contains(cmd, w) {
t.Errorf("wanted %q in %q", w, cmd)
}
- cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
+ // TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present
+ if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" {
+ t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries")
+ }
- if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
+ cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
+ if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) {
t.Errorf("wanted %q in %q", w, cmd)
}
}
@@ -2910,6 +3119,7 @@ func TestUncompressDex(t *testing.T) {
config := testAppConfig(nil, bp, nil)
if unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
+ config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}
ctx := testContext()
@@ -3190,6 +3400,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) {
res := variant.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
+ checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "")
checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag)
}
}
diff --git a/java/config/config.go b/java/config/config.go
index 95add017d..31e2b0ffe 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -28,11 +28,13 @@ import (
var (
pctx = android.NewPackageContext("android/soong/java/config")
- DefaultBootclasspathLibraries = []string{"core.platform.api.stubs", "core-lambda-stubs"}
- DefaultSystemModules = "core-platform-api-stubs-system-modules"
- DefaultLibraries = []string{"ext", "framework"}
- DefaultLambdaStubsLibrary = "core-lambda-stubs"
- SdkLambdaStubsPath = "prebuilts/sdk/tools/core-lambda-stubs.jar"
+ LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
+ LegacyCorePlatformSystemModules = "legacy-core-platform-api-stubs-system-modules"
+ StableCorePlatformBootclasspathLibraries = []string{"stable.core.platform.api.stubs", "core-lambda-stubs"}
+ StableCorePlatformSystemModules = "stable-core-platform-api-stubs-system-modules"
+ FrameworkLibraries = []string{"ext", "framework"}
+ DefaultLambdaStubsLibrary = "core-lambda-stubs"
+ SdkLambdaStubsPath = "prebuilts/sdk/tools/core-lambda-stubs.jar"
DefaultMakeJacocoExcludeFilter = []string{"org.junit.*", "org.jacoco.*", "org.mockito.*"}
DefaultJacocoExcludeFilter = []string{"org.junit.**", "org.jacoco.**", "org.mockito.**"}
@@ -112,7 +114,7 @@ func init() {
pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
- pctx.SourcePathVariable("GenKotlinBuildFileCmd", "build/soong/scripts/gen-kotlin-build-file.sh")
+ pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file.py")
pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh")
@@ -128,7 +130,7 @@ func init() {
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
pctx.VariableFunc("TurbineJar", func(ctx android.PackageVarContext) string {
turbine := "turbine.jar"
- if ctx.Config().UnbundledBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return "prebuilts/build-tools/common/framework/" + turbine
} else {
return ctx.Config().HostJavaToolPath(ctx, turbine).String()
@@ -148,9 +150,9 @@ func init() {
pctx.HostBinToolVariable("DexpreoptGen", "dexpreopt_gen")
pctx.VariableFunc("REJavaPool", remoteexec.EnvOverrideFunc("RBE_JAVA_POOL", "java16"))
- pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
- pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
- pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
+ pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
+ pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
pctx.VariableFunc("RETurbineExecStrategy", remoteexec.EnvOverrideFunc("RBE_TURBINE_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RESignApkExecStrategy", remoteexec.EnvOverrideFunc("RBE_SIGNAPK_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("REJarExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAR_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
@@ -163,7 +165,7 @@ func init() {
pctx.HostBinToolVariable("ManifestMergerCmd", "manifest-merger")
- pctx.HostBinToolVariable("Class2Greylist", "class2greylist")
+ pctx.HostBinToolVariable("Class2NonSdkList", "class2nonsdklist")
pctx.HostBinToolVariable("HiddenAPI", "hiddenapi")
hostBinToolVariableWithSdkToolsPrebuilt("Aapt2Cmd", "aapt2")
@@ -178,7 +180,7 @@ func init() {
func hostBinToolVariableWithSdkToolsPrebuilt(name, tool string) {
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
- if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return filepath.Join("prebuilts/sdk/tools", runtime.GOOS, "bin", tool)
} else {
return ctx.Config().HostToolPath(ctx, tool).String()
@@ -188,7 +190,7 @@ func hostBinToolVariableWithSdkToolsPrebuilt(name, tool string) {
func hostJavaToolVariableWithSdkToolsPrebuilt(name, tool string) {
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
- if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return filepath.Join("prebuilts/sdk/tools/lib", tool+".jar")
} else {
return ctx.Config().HostJavaToolPath(ctx, tool+".jar").String()
@@ -198,7 +200,7 @@ func hostJavaToolVariableWithSdkToolsPrebuilt(name, tool string) {
func hostJNIToolVariableWithSdkToolsPrebuilt(name, tool string) {
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
- if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
ext := ".so"
if runtime.GOOS == "darwin" {
ext = ".dylib"
@@ -212,7 +214,7 @@ func hostJNIToolVariableWithSdkToolsPrebuilt(name, tool string) {
func hostBinToolVariableWithBuildToolsPrebuilt(name, tool string) {
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
- if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return filepath.Join("prebuilts/build-tools", ctx.Config().PrebuiltOS(), "bin", tool)
} else {
return ctx.Config().HostToolPath(ctx, tool).String()
diff --git a/java/config/makevars.go b/java/config/makevars.go
index b355fad87..df447a129 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -25,9 +25,11 @@ func init() {
}
func makeVarsProvider(ctx android.MakeVarsContext) {
- ctx.Strict("TARGET_DEFAULT_JAVA_LIBRARIES", strings.Join(DefaultLibraries, " "))
- ctx.Strict("TARGET_DEFAULT_BOOTCLASSPATH_LIBRARIES", strings.Join(DefaultBootclasspathLibraries, " "))
- ctx.Strict("DEFAULT_SYSTEM_MODULES", DefaultSystemModules)
+ ctx.Strict("FRAMEWORK_LIBRARIES", strings.Join(FrameworkLibraries, " "))
+
+ // These are used by make when LOCAL_PRIVATE_PLATFORM_APIS is set (equivalent to platform_apis in blueprint):
+ ctx.Strict("LEGACY_CORE_PLATFORM_BOOTCLASSPATH_LIBRARIES", strings.Join(LegacyCorePlatformBootclasspathLibraries, " "))
+ ctx.Strict("LEGACY_CORE_PLATFORM_SYSTEM_MODULES", LegacyCorePlatformSystemModules)
ctx.Strict("ANDROID_JAVA_HOME", "${JavaHome}")
ctx.Strict("ANDROID_JAVA8_HOME", "prebuilts/jdk/jdk8/${hostPrebuiltTag}")
@@ -73,7 +75,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) {
ctx.Strict("ANDROID_MANIFEST_MERGER", "${ManifestMergerCmd}")
- ctx.Strict("CLASS2GREYLIST", "${Class2Greylist}")
+ ctx.Strict("CLASS2NONSDKLIST", "${Class2NonSdkList}")
ctx.Strict("HIDDENAPI", "${HiddenAPI}")
ctx.Strict("DEX_FLAGS", "${DexFlags}")
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 11e68eb6c..40a2280d9 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -19,6 +19,7 @@ import (
"io"
"android/soong/android"
+ "android/soong/dexpreopt"
)
type DeviceHostConverter struct {
@@ -150,7 +151,11 @@ func (d *DeviceHostConverter) ImplementationAndResourcesJars() android.Paths {
return d.implementationAndResourceJars
}
-func (d *DeviceHostConverter) DexJar() android.Path {
+func (d *DeviceHostConverter) DexJarBuildPath() android.Path {
+ return nil
+}
+
+func (d *DeviceHostConverter) DexJarInstallPath() android.Path {
return nil
}
@@ -158,7 +163,7 @@ func (d *DeviceHostConverter) AidlIncludeDirs() android.Paths {
return nil
}
-func (d *DeviceHostConverter) ExportedSdkLibs() []string {
+func (d *DeviceHostConverter) ExportedSdkLibs() dexpreopt.LibraryPaths {
return nil
}
diff --git a/java/dex.go b/java/dex.go
index 9e61e95ad..c85914c41 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -24,6 +24,61 @@ import (
"android/soong/remoteexec"
)
+type DexProperties struct {
+ // If set to true, compile dex regardless of installable. Defaults to false.
+ Compile_dex *bool
+
+ // list of module-specific flags that will be used for dex compiles
+ Dxflags []string `android:"arch_variant"`
+
+ Optimize struct {
+ // If false, disable all optimization. Defaults to true for android_app and android_test
+ // modules, false for java_library and java_test modules.
+ Enabled *bool
+ // True if the module containing this has it set by default.
+ EnabledByDefault bool `blueprint:"mutated"`
+
+ // If true, optimize for size by removing unused code. Defaults to true for apps,
+ // false for libraries and tests.
+ Shrink *bool
+
+ // If true, optimize bytecode. Defaults to false.
+ Optimize *bool
+
+ // If true, obfuscate bytecode. Defaults to false.
+ Obfuscate *bool
+
+ // If true, do not use the flag files generated by aapt that automatically keep
+ // classes referenced by the app manifest. Defaults to false.
+ No_aapt_flags *bool
+
+ // Flags to pass to proguard.
+ Proguard_flags []string
+
+ // Specifies the locations of files containing proguard flags.
+ Proguard_flags_files []string `android:"path"`
+ }
+
+ // Keep the data uncompressed. We always need uncompressed dex for execution,
+ // so this might actually save space by avoiding storing the same data twice.
+ // This defaults to reasonable value based on module and should not be set.
+ // It exists only to support ART tests.
+ Uncompress_dex *bool
+}
+
+type dexer struct {
+ dexProperties DexProperties
+
+ // list of extra proguard flag files
+ extraProguardFlagFiles android.Paths
+ proguardDictionary android.OptionalPath
+ proguardUsageZip android.OptionalPath
+}
+
+func (d *dexer) effectiveOptimizeEnabled() bool {
+ return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
+}
+
var d8, d8RE = remoteexec.MultiCommandStaticRules(pctx, "d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -55,13 +110,17 @@ var d8, d8RE = remoteexec.MultiCommandStaticRules(pctx, "d8",
var r8, r8RE = remoteexec.MultiCommandStaticRules(pctx, "r8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `rm -f "$outDict" && ` +
+ `rm -f "$outDict" && rm -rf "${outUsageDir}" && ` +
+ `mkdir -p $$(dirname ${outUsage}) && ` +
`$r8Template${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
`--force-proguard-compatibility ` +
`--no-data-resources ` +
- `-printmapping $outDict ` +
+ `-printmapping ${outDict} ` +
+ `-printusage ${outUsage} ` +
`$r8Flags && ` +
- `touch "$outDict" && ` +
+ `touch "${outDict}" "${outUsage}" && ` +
+ `${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" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
@@ -84,10 +143,18 @@ var r8, r8RE = remoteexec.MultiCommandStaticRules(pctx, "r8",
ExecStrategy: "${config.RER8ExecStrategy}",
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
- }, []string{"outDir", "outDict", "r8Flags", "zipFlags"}, []string{"implicits"})
+ "$zipUsageTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "${outUsage}"},
+ OutputFiles: []string{"${outUsageZip}"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ }, []string{"outDir", "outDict", "outUsage", "outUsageZip", "outUsageDir",
+ "r8Flags", "zipFlags"}, []string{"implicits"})
-func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
- flags := j.deviceProperties.Dxflags
+func (d *dexer) dexCommonFlags(ctx android.ModuleContext, minSdkVersion sdkSpec) []string {
+ flags := d.dexProperties.Dxflags
// Translate all the DX flags to D8 ones until all the build files have been migrated
// to D8 flags. See: b/69377755
flags = android.RemoveListFromList(flags,
@@ -103,30 +170,27 @@ func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
"--verbose")
}
- minSdkVersion, err := j.minSdkVersion().effectiveVersion(ctx)
+ effectiveVersion, err := minSdkVersion.effectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
- flags = append(flags, "--min-api "+minSdkVersion.asNumberString())
+ flags = append(flags, "--min-api "+effectiveVersion.asNumberString())
return flags
}
-func (j *Module) d8Flags(ctx android.ModuleContext, flags javaBuilderFlags) ([]string, android.Paths) {
- d8Flags := j.dexCommonFlags(ctx)
-
+func d8Flags(flags javaBuilderFlags) (d8Flags []string, d8Deps android.Paths) {
d8Flags = append(d8Flags, flags.bootClasspath.FormRepeatedClassPath("--lib ")...)
d8Flags = append(d8Flags, flags.classpath.FormRepeatedClassPath("--lib ")...)
- var d8Deps android.Paths
d8Deps = append(d8Deps, flags.bootClasspath...)
d8Deps = append(d8Deps, flags.classpath...)
return d8Flags, d8Deps
}
-func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Flags []string, r8Deps android.Paths) {
- opt := j.deviceProperties.Optimize
+func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Flags []string, r8Deps android.Paths) {
+ opt := d.dexProperties.Optimize
// 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
@@ -140,8 +204,6 @@ func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8F
proguardRaiseDeps = append(proguardRaiseDeps, dep.(Dependency).HeaderJars()...)
})
- r8Flags = append(r8Flags, j.dexCommonFlags(ctx)...)
-
r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
r8Flags = append(r8Flags, flags.classpath.FormJavaClassPath("-libraryjars"))
@@ -154,15 +216,10 @@ func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8F
android.PathForSource(ctx, "build/make/core/proguard.flags"),
}
- if j.shouldInstrumentStatic(ctx) {
- flagFiles = append(flagFiles,
- android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
- }
-
- flagFiles = append(flagFiles, j.extraProguardFlagFiles...)
+ flagFiles = append(flagFiles, d.extraProguardFlagFiles...)
// TODO(ccross): static android library proguard files
- flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, j.deviceProperties.Optimize.Proguard_flags_files)...)
+ flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, opt.Proguard_flags_files)...)
r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
r8Deps = append(r8Deps, flagFiles...)
@@ -171,7 +228,7 @@ func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8F
r8Deps = append(r8Deps, android.PathForSource(ctx,
"build/make/core/proguard_basic_keeps.flags"))
- r8Flags = append(r8Flags, j.deviceProperties.Optimize.Proguard_flags...)
+ r8Flags = append(r8Flags, opt.Proguard_flags...)
// TODO(ccross): Don't shrink app instrumentation tests by default.
if !Bool(opt.Shrink) {
@@ -197,46 +254,55 @@ func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8F
return r8Flags, r8Deps
}
-func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
+func (d *dexer) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, minSdkVersion sdkSpec,
classesJar android.Path, jarName string) android.ModuleOutPath {
- useR8 := j.deviceProperties.EffectiveOptimizeEnabled()
-
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
outDir := android.PathForModuleOut(ctx, "dex")
zipFlags := "--ignore_missing_files"
- if proptools.Bool(j.deviceProperties.Uncompress_dex) {
+ if proptools.Bool(d.dexProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
+ commonFlags := d.dexCommonFlags(ctx, minSdkVersion)
+
+ useR8 := d.effectiveOptimizeEnabled()
if useR8 {
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
- j.proguardDictionary = proguardDictionary
- r8Flags, r8Deps := j.r8Flags(ctx, flags)
+ d.proguardDictionary = android.OptionalPathForPath(proguardDictionary)
+ proguardUsageDir := android.PathForModuleOut(ctx, "proguard_usage")
+ proguardUsage := proguardUsageDir.Join(ctx, ctx.Namespace().Path,
+ android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
+ proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
+ d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
+ r8Flags, r8Deps := d.r8Flags(ctx, flags)
rule := r8
args := map[string]string{
- "r8Flags": strings.Join(r8Flags, " "),
- "zipFlags": zipFlags,
- "outDict": j.proguardDictionary.String(),
- "outDir": outDir.String(),
+ "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "),
+ "zipFlags": zipFlags,
+ "outDict": proguardDictionary.String(),
+ "outUsageDir": proguardUsageDir.String(),
+ "outUsage": proguardUsage.String(),
+ "outUsageZip": proguardUsageZip.String(),
+ "outDir": outDir.String(),
}
if ctx.Config().IsEnvTrue("RBE_R8") {
rule = r8RE
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
ctx.Build(pctx, android.BuildParams{
- Rule: rule,
- Description: "r8",
- Output: javalibJar,
- ImplicitOutput: proguardDictionary,
- Input: classesJar,
- Implicits: r8Deps,
- Args: args,
+ Rule: rule,
+ Description: "r8",
+ Output: javalibJar,
+ ImplicitOutputs: android.WritablePaths{proguardDictionary, proguardUsageZip},
+ Input: classesJar,
+ Implicits: r8Deps,
+ Args: args,
})
} else {
- d8Flags, d8Deps := j.d8Flags(ctx, flags)
+ d8Flags, d8Deps := d8Flags(flags)
rule := d8
if ctx.Config().IsEnvTrue("RBE_D8") {
rule = d8RE
@@ -248,13 +314,13 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
Input: classesJar,
Implicits: d8Deps,
Args: map[string]string{
- "d8Flags": strings.Join(d8Flags, " "),
+ "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
"zipFlags": zipFlags,
"outDir": outDir.String(),
},
})
}
- if proptools.Bool(j.deviceProperties.Uncompress_dex) {
+ if proptools.Bool(d.dexProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName)
TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
javalibJar = alignedJavalibJar
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 28a2c8ae6..f1b717874 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -37,7 +37,7 @@ type dexpreopter struct {
usesLibs []string
optionalUsesLibs []string
enforceUsesLibs bool
- libraryPaths map[string]android.Path
+ libraryPaths dexpreopt.LibraryPaths
builtInstalled string
}
@@ -77,10 +77,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
return true
}
- if ctx.Config().UnbundledBuild() {
- return true
- }
-
if d.isTest {
return true
}
@@ -131,7 +127,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
global := dexpreopt.GetGlobalConfig(ctx)
bootImage := defaultBootImageConfig(ctx)
dexFiles := bootImage.dexPathsDeps.Paths()
- dexLocations := bootImage.dexLocationsDeps
+ // The dex locations for all Android variants are identical.
+ dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps
if global.UseArtImage {
bootImage = artBootImageConfig(ctx)
}
@@ -159,6 +156,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
images = append(images, variant.images)
imagesDeps = append(imagesDeps, variant.imagesDeps)
}
+ // The image locations for all Android variants are identical.
+ imageLocations := bootImage.getAnyAndroidVariant().imageLocations()
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
@@ -174,7 +173,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
profileBootListing = android.ExistentPathForSource(ctx,
ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot")
profileIsTextListing = true
- } else {
+ } else if global.ProfileDir != "" {
profileClassListing = android.ExistentPathForSource(ctx,
global.ProfileDir, ctx.ModuleName()+".prof")
}
@@ -194,15 +193,15 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
ProfileIsTextListing: profileIsTextListing,
ProfileBootListing: profileBootListing,
- EnforceUsesLibraries: d.enforceUsesLibs,
- PresentOptionalUsesLibraries: d.optionalUsesLibs,
- UsesLibraries: d.usesLibs,
- LibraryPaths: d.libraryPaths,
+ EnforceUsesLibraries: d.enforceUsesLibs,
+ OptionalUsesLibraries: d.optionalUsesLibs,
+ UsesLibraries: d.usesLibs,
+ LibraryPaths: d.libraryPaths,
Archs: archs,
DexPreoptImages: images,
DexPreoptImagesDeps: imagesDeps,
- DexPreoptImageLocations: bootImage.imageLocations,
+ DexPreoptImageLocations: imageLocations,
PreoptBootClassPathDexFiles: dexFiles,
PreoptBootClassPathDexLocations: dexLocations,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 2f0cbdb8c..3addc1a74 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -29,29 +29,10 @@ func init() {
RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext)
}
-// The image "location" is a symbolic path that with multiarchitecture
-// support doesn't really exist on the device. Typically it is
-// /system/framework/boot.art and should be the same for all supported
-// architectures on the device. The concrete architecture specific
-// content actually ends up in a "filename" that contains an
-// architecture specific directory name such as arm, arm64, mips,
-// mips64, x86, x86_64.
-//
-// Here are some example values for an x86_64 / x86 configuration:
-//
-// bootImages["x86_64"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art"
-// dexpreopt.PathToLocation(bootImages["x86_64"], "x86_64") = "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
-//
-// bootImages["x86"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86/boot.art"
-// dexpreopt.PathToLocation(bootImages["x86"])= "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
-//
-// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
-// will then reconstruct the real path, so the rules must have a dependency on the real path.
-
// Target-independent description of pre-compiled boot image.
type bootImageConfig struct {
- // Whether this image is an extension.
- extension bool
+ // If this image is an extension, the image that it extends.
+ extends *bootImageConfig
// Image name (used in directory names and ninja rule names).
name string
@@ -68,20 +49,13 @@ type bootImageConfig struct {
// Subdirectory where the image files are installed.
installSubdir string
- // The names of jars that constitute this image.
- modules []string
-
- // The "locations" of jars.
- dexLocations []string // for this image
- dexLocationsDeps []string // for the dependency images and in this image
+ // A list of (location, jar) pairs for the Java modules in this image.
+ modules android.ConfiguredJarList
// File paths to jars.
dexPaths android.WritablePaths // for this image
dexPathsDeps android.WritablePaths // for the dependency images and in this image
- // The "locations" of the dependency images and in this image.
- imageLocations []string
-
// File path to a zip archive with all image files (or nil, if not needed).
zip android.WritablePath
@@ -99,6 +73,10 @@ type bootImageVariant struct {
// Target for which the image is generated.
target android.Target
+ // The "locations" of jars.
+ dexLocations []string // for this image
+ dexLocationsDeps []string // for the dependency images and in this image
+
// Paths to image files.
images android.OutputPath // first image file
imagesDeps android.OutputPaths // all files
@@ -121,30 +99,40 @@ func (image bootImageConfig) getVariant(target android.Target) *bootImageVariant
return nil
}
-func (image bootImageConfig) moduleName(idx int) string {
+// Return any (the first) variant which is for the device (as opposed to for the host)
+func (image bootImageConfig) getAnyAndroidVariant() *bootImageVariant {
+ for _, variant := range image.variants {
+ if variant.target.Os == android.Android {
+ return variant
+ }
+ }
+ return nil
+}
+
+func (image bootImageConfig) moduleName(ctx android.PathContext, idx int) string {
// Dexpreopt on the boot class path produces multiple files. The first dex file
// is converted into 'name'.art (to match the legacy assumption that 'name'.art
// exists), and the rest are converted to 'name'-<jar>.art.
- m := image.modules[idx]
+ m := image.modules.Jar(idx)
name := image.stem
- if idx != 0 || image.extension {
- name += "-" + stemOf(m)
+ if idx != 0 || image.extends != nil {
+ name += "-" + android.ModuleStem(m)
}
return name
}
-func (image bootImageConfig) firstModuleNameOrStem() string {
- if len(image.modules) > 0 {
- return image.moduleName(0)
+func (image bootImageConfig) firstModuleNameOrStem(ctx android.PathContext) string {
+ if image.modules.Len() > 0 {
+ return image.moduleName(ctx, 0)
} else {
return image.stem
}
}
func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths {
- ret := make(android.OutputPaths, 0, len(image.modules)*len(exts))
- for i := range image.modules {
- name := image.moduleName(i)
+ ret := make(android.OutputPaths, 0, image.modules.Len()*len(exts))
+ for i := 0; i < image.modules.Len(); i++ {
+ name := image.moduleName(ctx, i)
for _, ext := range exts {
ret = append(ret, dir.Join(ctx, name+ext))
}
@@ -152,6 +140,24 @@ func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.Ou
return ret
}
+// The image "location" is a symbolic path that, with multiarchitecture support, doesn't really
+// exist on the device. Typically it is /apex/com.android.art/javalib/boot.art and should be the
+// same for all supported architectures on the device. The concrete architecture specific files
+// actually end up in architecture-specific sub-directory such as arm, arm64, x86, or x86_64.
+//
+// For example a physical file
+// "/apex/com.android.art/javalib/x86/boot.art" has "image location"
+// "/apex/com.android.art/javalib/boot.art" (which is not an actual file).
+//
+// The location is passed as an argument to the ART tools like dex2oat instead of the real path.
+// ART tools will then reconstruct the architecture-specific real path.
+func (image *bootImageVariant) imageLocations() (imageLocations []string) {
+ if image.extends != nil {
+ imageLocations = image.extends.getVariant(image.target).imageLocations()
+ }
+ return append(imageLocations, dexpreopt.PathToLocation(image.images, image.target.Arch.ArchType))
+}
+
func concat(lists ...[]string) []string {
var size int
for _, l := range lists {
@@ -173,20 +179,7 @@ func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
}
func skipDexpreoptBootJars(ctx android.PathContext) bool {
- if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
- return true
- }
-
- if ctx.Config().UnbundledBuild() {
- return true
- }
-
- if len(ctx.Config().Targets[android.Android]) == 0 {
- // Host-only build
- return true
- }
-
- return false
+ return dexpreopt.GetGlobalConfig(ctx).DisablePreopt
}
type dexpreoptBootJars struct {
@@ -204,7 +197,10 @@ func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]and
// Include dexpreopt files for the primary boot image.
files := map[android.ArchType]android.OutputPaths{}
for _, variant := range artBootImageConfig(ctx).variants {
- files[variant.target.Arch.ArchType] = variant.imagesDeps
+ // We also generate boot images for host (for testing), but we don't need those in the apex.
+ if variant.target.Os == android.Android {
+ files[variant.target.Arch.ArchType] = variant.imagesDeps
+ }
}
return files
}
@@ -251,13 +247,13 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
return -1, nil
}
- jar, hasJar := module.(interface{ DexJar() android.Path })
+ jar, hasJar := module.(interface{ DexJarBuildPath() android.Path })
if !hasJar {
return -1, nil
}
name := ctx.ModuleName(module)
- index := android.IndexList(name, image.modules)
+ index := image.modules.IndexOfJar(name)
if index == -1 {
return -1, nil
}
@@ -266,7 +262,7 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
apex, isApexModule := module.(android.ApexModule)
fromUpdatableApex := isApexModule && apex.Updatable()
if image.name == artBootImageName {
- if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") {
+ if isApexModule && len(apex.InApexes()) > 0 && allHavePrefix(apex.InApexes(), "com.android.art.") {
// ok: found the jar in the ART apex
} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
// exception (skip and continue): special "hostdex" platform variant
@@ -276,30 +272,39 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
return -1, nil
} else if fromUpdatableApex {
// error: this jar is part of an updatable apex other than ART
- ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
+ ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apex.InApexes())
} else {
// error: this jar is part of the platform or a non-updatable apex
- ctx.Errorf("module '%s' is not allowed in the ART boot image", name)
+ ctx.Errorf("module %q is not allowed in the ART boot image", name)
}
} else if image.name == frameworkBootImageName {
if !fromUpdatableApex {
// ok: this jar is part of the platform or a non-updatable apex
} else {
// error: this jar is part of an updatable apex
- ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName())
+ ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apex.InApexes())
}
} else {
panic("unknown boot image: " + image.name)
}
- return index, jar.DexJar()
+ return index, jar.DexJarBuildPath()
+}
+
+func allHavePrefix(list []string, prefix string) bool {
+ for _, s := range list {
+ if !strings.HasPrefix(s, prefix) {
+ return false
+ }
+ }
+ return true
}
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
// Collect dex jar paths for the boot image modules.
// This logic is tested in the apex package to avoid import cycle apex <-> java.
- bootDexJars := make(android.Paths, len(image.modules))
+ bootDexJars := make(android.Paths, image.modules.Len())
ctx.VisitAllModules(func(module android.Module) {
if i, j := getBootImageJar(ctx, image, module); i != -1 {
bootDexJars[i] = j
@@ -310,13 +315,13 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
// Ensure all modules were converted to paths
for i := range bootDexJars {
if bootDexJars[i] == nil {
+ m := image.modules.Jar(i)
if ctx.Config().AllowMissingDependencies() {
- missingDeps = append(missingDeps, image.modules[i])
+ missingDeps = append(missingDeps, m)
bootDexJars[i] = android.PathForOutput(ctx, "missing")
} else {
ctx.Errorf("failed to find a dex jar path for module '%s'"+
- ", note that some jars may be filtered out by module constraints",
- image.modules[i])
+ ", note that some jars may be filtered out by module constraints", m)
}
}
}
@@ -336,10 +341,12 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
bootFrameworkProfileRule(ctx, image, missingDeps)
updatableBcpPackagesRule(ctx, image, missingDeps)
- var allFiles android.Paths
+ var zipFiles android.Paths
for _, variant := range image.variants {
files := buildBootImageVariant(ctx, variant, profile, missingDeps)
- allFiles = append(allFiles, files.Paths()...)
+ if variant.target.Os == android.Android {
+ zipFiles = append(zipFiles, files.Paths()...)
+ }
}
if image.zip != nil {
@@ -347,8 +354,8 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
rule.Command().
BuiltTool(ctx, "soong_zip").
FlagWithOutput("-o ", image.zip).
- FlagWithArg("-C ", image.dir.String()).
- FlagWithInputList("-f ", allFiles, " -f ")
+ FlagWithArg("-C ", image.dir.Join(ctx, android.Android.String()).String()).
+ FlagWithInputList("-f ", zipFiles, " -f ")
rule.Build(pctx, ctx, "zip_"+image.name, "zip "+image.name+" image")
}
@@ -363,9 +370,10 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
global := dexpreopt.GetGlobalConfig(ctx)
arch := image.target.Arch.ArchType
- symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
+ os := image.target.Os.String() // We need to distinguish host-x86 and device-x86.
+ symbolsDir := image.symbolsDir.Join(ctx, os, image.installSubdir, arch.String())
symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
- outputDir := image.dir.Join(ctx, image.installSubdir, arch.String())
+ outputDir := image.dir.Join(ctx, os, image.installSubdir, arch.String())
outputPath := outputDir.Join(ctx, image.stem+".oat")
oatLocation := dexpreopt.PathToLocation(outputPath, arch)
imagePath := outputPath.ReplaceExtension(ctx, "art")
@@ -411,7 +419,7 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
}
- if image.extension {
+ if image.extends != nil {
artImage := image.primaryImages
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
@@ -433,13 +441,18 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
FlagWithArg("--oat-location=", oatLocation).
FlagWithArg("--image=", imagePath.String()).
FlagWithArg("--instruction-set=", arch.String()).
- FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]).
- FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]).
FlagWithArg("--android-root=", global.EmptyDirectory).
FlagWithArg("--no-inline-from=", "core-oj.jar").
Flag("--force-determinism").
Flag("--abort-on-hard-verifier-error")
+ // Use the default variant/features for host builds.
+ // The map below contains only device CPU info (which might be x86 on some devices).
+ if image.target.Os == android.Android {
+ cmd.FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch])
+ cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch])
+ }
+
if global.BootFlags != "" {
cmd.Flag(global.BootFlags)
}
@@ -451,7 +464,6 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape(failureMessage))
installDir := filepath.Join("/", image.installSubdir, arch.String())
- vdexInstallDir := filepath.Join("/", image.installSubdir)
var vdexInstalls android.RuleBuilderInstalls
var unstrippedInstalls android.RuleBuilderInstalls
@@ -470,11 +482,10 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
cmd.ImplicitOutput(vdex)
zipFiles = append(zipFiles, vdex)
- // The vdex files are identical between architectures, install them to a shared location. The Make rules will
- // only use the install rules for one architecture, and will create symlinks into the architecture-specific
- // directories.
+ // Note that the vdex files are identical between architectures.
+ // Make rules will create symlinks to share them between architectures.
vdexInstalls = append(vdexInstalls,
- android.RuleBuilderInstall{vdex, filepath.Join(vdexInstallDir, vdex.Base())})
+ android.RuleBuilderInstall{vdex, filepath.Join(installDir, vdex.Base())})
}
for _, unstrippedOat := range image.moduleFiles(ctx, symbolsDir, ".oat") {
@@ -485,7 +496,7 @@ func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant
android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())})
}
- rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+arch.String(), "dexpreopt "+image.name+" jars "+arch.String())
+ rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+image.target.String(), "dexpreopt "+image.name+" jars "+arch.String())
// save output and installed files for makevars
image.installs = rule.Installs()
@@ -503,7 +514,7 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImageConfig,
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
- if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
+ if global.DisableGenerateProfile || ctx.Config().UnbundledBuild() {
return nil
}
profile := ctx.Config().Once(bootImageProfileRuleKey, func() interface{} {
@@ -535,7 +546,7 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImageConfig,
Tool(globalSoong.Profman).
FlagWithInput("--create-profile-from=", bootImageProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocationsDeps).
+ FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.prof")
@@ -558,7 +569,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConf
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
- if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
+ if global.DisableGenerateProfile || ctx.Config().UnbundledBuild() {
return nil
}
return ctx.Config().Once(bootFrameworkProfileRuleKey, func() interface{} {
@@ -586,7 +597,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConf
Flag("--generate-boot-profile").
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocationsDeps).
+ FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.bprof")
@@ -600,13 +611,13 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConf
var bootFrameworkProfileRuleKey = android.NewOnceKey("bootFrameworkProfileRule")
func updatableBcpPackagesRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
- if ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
+ if ctx.Config().UnbundledBuild() {
return nil
}
return ctx.Config().Once(updatableBcpPackagesRuleKey, func() interface{} {
global := dexpreopt.GetGlobalConfig(ctx)
- updatableModules := dexpreopt.GetJarsFromApexJarPairs(global.UpdatableBootJars)
+ updatableModules := global.UpdatableBootJars.CopyOfJars()
// Collect `permitted_packages` for updatable boot jars.
var updatablePackages []string
@@ -658,27 +669,32 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImageConfig) {
var allPhonies android.Paths
for _, image := range image.variants {
arch := image.target.Arch.ArchType
+ suffix := arch.String()
+ // Host and target might both use x86 arch. We need to ensure the names are unique.
+ if image.target.Os.Class == android.Host {
+ suffix = "host-" + suffix
+ }
// Create a rule to call oatdump.
- output := android.PathForOutput(ctx, "boot."+arch.String()+".oatdump.txt")
+ output := android.PathForOutput(ctx, "boot."+suffix+".oatdump.txt")
rule := android.NewRuleBuilder()
rule.Command().
// TODO: for now, use the debug version for better error reporting
BuiltTool(ctx, "oatdumpd").
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
- FlagWithArg("--image=", strings.Join(image.imageLocations, ":")).Implicits(image.imagesDeps.Paths()).
+ FlagWithArg("--image=", strings.Join(image.imageLocations(), ":")).Implicits(image.imagesDeps.Paths()).
FlagWithOutput("--output=", output).
FlagWithArg("--instruction-set=", arch.String())
- rule.Build(pctx, ctx, "dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+ rule.Build(pctx, ctx, "dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
// Create a phony rule that depends on the output file and prints the path.
- phony := android.PathForPhony(ctx, "dump-oat-boot-"+arch.String())
+ phony := android.PathForPhony(ctx, "dump-oat-boot-"+suffix)
rule = android.NewRuleBuilder()
rule.Command().
Implicit(output).
ImplicitOutput(phony).
Text("echo").FlagWithArg("Output in ", output.String())
- rule.Build(pctx, ctx, "phony-dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
+ rule.Build(pctx, ctx, "phony-dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
allPhonies = append(allPhonies, phony)
}
@@ -716,21 +732,25 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
if image != nil {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
- ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.getAnyAndroidVariant().dexLocationsDeps, " "))
var imageNames []string
for _, current := range append(d.otherImages, image) {
imageNames = append(imageNames, current.name)
- for _, current := range current.variants {
- sfx := current.name + "_" + current.target.Arch.ArchType.String()
- ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls.String())
- ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images.String())
- ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps.Strings(), " "))
- ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs.String())
- ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls.String())
+ for _, variant := range current.variants {
+ suffix := ""
+ if variant.target.Os.Class == android.Host {
+ suffix = "_host"
+ }
+ sfx := variant.name + suffix + "_" + variant.target.Arch.ArchType.String()
+ ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, variant.vdexInstalls.String())
+ ctx.Strict("DEXPREOPT_IMAGE_"+sfx, variant.images.String())
+ ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(variant.imagesDeps.Strings(), " "))
+ ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, variant.installs.String())
+ ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, variant.unstrippedInstalls.String())
}
-
- ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(current.imageLocations, ":"))
+ imageLocations := current.getAnyAndroidVariant().imageLocations()
+ ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(imageLocations, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
}
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index e7b3c3ba9..4a8d3cd50 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -24,7 +24,7 @@ import (
"android/soong/dexpreopt"
)
-func TestDexpreoptBootJars(t *testing.T) {
+func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOutputs []string) {
bp := `
java_sdk_library {
name: "foo",
@@ -48,67 +48,88 @@ func TestDexpreoptBootJars(t *testing.T) {
pathCtx := android.PathContextForTesting(config)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
+ dexpreoptConfig.BootJars = android.CreateConfiguredJarList(pathCtx, []string{"platform:foo", "platform:bar", "platform:baz"})
dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext()
-
RegisterDexpreoptBootJarsComponents(ctx)
-
run(t, ctx, config)
dexpreoptBootJars := ctx.SingletonForTests("dex_bootjars")
-
- bootArt := dexpreoptBootJars.Output("boot-foo.art")
-
- expectedInputs := []string{
- "dex_artjars/apex/com.android.art/javalib/arm64/boot.art",
- "dex_bootjars_input/foo.jar",
- "dex_bootjars_input/bar.jar",
- "dex_bootjars_input/baz.jar",
- }
+ rule := dexpreoptBootJars.Output(ruleFile)
for i := range expectedInputs {
expectedInputs[i] = filepath.Join(buildDir, "test_device", expectedInputs[i])
}
- inputs := bootArt.Implicits.Strings()
+ for i := range expectedOutputs {
+ expectedOutputs[i] = filepath.Join(buildDir, "test_device", expectedOutputs[i])
+ }
+
+ inputs := rule.Implicits.Strings()
sort.Strings(inputs)
sort.Strings(expectedInputs)
+ outputs := append(android.WritablePaths{rule.Output}, rule.ImplicitOutputs...).Strings()
+ sort.Strings(outputs)
+ sort.Strings(expectedOutputs)
+
if !reflect.DeepEqual(inputs, expectedInputs) {
t.Errorf("want inputs %q\n got inputs %q", expectedInputs, inputs)
}
- expectedOutputs := []string{
- "dex_bootjars/system/framework/arm64/boot.invocation",
-
- "dex_bootjars/system/framework/arm64/boot-foo.art",
- "dex_bootjars/system/framework/arm64/boot-bar.art",
- "dex_bootjars/system/framework/arm64/boot-baz.art",
-
- "dex_bootjars/system/framework/arm64/boot-foo.oat",
- "dex_bootjars/system/framework/arm64/boot-bar.oat",
- "dex_bootjars/system/framework/arm64/boot-baz.oat",
+ if !reflect.DeepEqual(outputs, expectedOutputs) {
+ t.Errorf("want outputs %q\n got outputs %q", expectedOutputs, outputs)
+ }
+}
- "dex_bootjars/system/framework/arm64/boot-foo.vdex",
- "dex_bootjars/system/framework/arm64/boot-bar.vdex",
- "dex_bootjars/system/framework/arm64/boot-baz.vdex",
+func TestDexpreoptBootJars(t *testing.T) {
+ ruleFile := "boot-foo.art"
- "dex_bootjars_unstripped/system/framework/arm64/boot-foo.oat",
- "dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
- "dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
+ expectedInputs := []string{
+ "dex_artjars/android/apex/com.android.art/javalib/arm64/boot.art",
+ "dex_bootjars_input/foo.jar",
+ "dex_bootjars_input/bar.jar",
+ "dex_bootjars_input/baz.jar",
}
- for i := range expectedOutputs {
- expectedOutputs[i] = filepath.Join(buildDir, "test_device", expectedOutputs[i])
+ expectedOutputs := []string{
+ "dex_bootjars/android/system/framework/arm64/boot.invocation",
+ "dex_bootjars/android/system/framework/arm64/boot-foo.art",
+ "dex_bootjars/android/system/framework/arm64/boot-bar.art",
+ "dex_bootjars/android/system/framework/arm64/boot-baz.art",
+ "dex_bootjars/android/system/framework/arm64/boot-foo.oat",
+ "dex_bootjars/android/system/framework/arm64/boot-bar.oat",
+ "dex_bootjars/android/system/framework/arm64/boot-baz.oat",
+ "dex_bootjars/android/system/framework/arm64/boot-foo.vdex",
+ "dex_bootjars/android/system/framework/arm64/boot-bar.vdex",
+ "dex_bootjars/android/system/framework/arm64/boot-baz.vdex",
+ "dex_bootjars_unstripped/android/system/framework/arm64/boot-foo.oat",
+ "dex_bootjars_unstripped/android/system/framework/arm64/boot-bar.oat",
+ "dex_bootjars_unstripped/android/system/framework/arm64/boot-baz.oat",
}
- outputs := append(android.WritablePaths{bootArt.Output}, bootArt.ImplicitOutputs...).Strings()
- sort.Strings(outputs)
- sort.Strings(expectedOutputs)
+ testDexpreoptBoot(t, ruleFile, expectedInputs, expectedOutputs)
+}
- if !reflect.DeepEqual(outputs, expectedOutputs) {
- t.Errorf("want outputs %q\n got outputs %q", expectedOutputs, outputs)
+// Changes to the boot.zip structure may break the ART APK scanner.
+func TestDexpreoptBootZip(t *testing.T) {
+ ruleFile := "boot.zip"
+
+ ctx := android.PathContextForTesting(testConfig(nil, "", nil))
+ expectedInputs := []string{}
+ for _, target := range ctx.Config().Targets[android.Android] {
+ for _, ext := range []string{".art", ".oat", ".vdex"} {
+ for _, jar := range []string{"foo", "bar", "baz"} {
+ expectedInputs = append(expectedInputs,
+ filepath.Join("dex_bootjars", target.Os.String(), "system/framework", target.Arch.ArchType.String(), "boot-"+jar+ext))
+ }
+ }
}
+
+ expectedOutputs := []string{
+ "dex_bootjars/boot.zip",
+ }
+
+ testDexpreoptBoot(t, ruleFile, expectedInputs, expectedOutputs)
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index f8356d188..f0d82ff92 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -37,14 +37,12 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string {
filepath.Join("/system/framework", m+".jar"))
}
// 2) The jars that are from an updatable apex.
- for _, m := range global.UpdatableSystemServerJars {
- systemServerClasspathLocations = append(systemServerClasspathLocations,
- dexpreopt.GetJarLocationFromApexJarPair(m))
- }
- if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) {
+ systemServerClasspathLocations = append(systemServerClasspathLocations,
+ global.UpdatableSystemServerJars.DevicePaths(ctx.Config(), android.Android)...)
+ if len(systemServerClasspathLocations) != len(global.SystemServerJars)+global.UpdatableSystemServerJars.Len() {
panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d",
len(systemServerClasspathLocations),
- len(global.SystemServerJars)+len(global.UpdatableSystemServerJars)))
+ len(global.SystemServerJars)+global.UpdatableSystemServerJars.Len()))
}
return systemServerClasspathLocations
})
@@ -61,20 +59,14 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target {
targets = append(targets, target)
}
}
+ // We may also need the images on host in order to run host-based tests.
+ for _, target := range ctx.Config().Targets[android.BuildOs] {
+ targets = append(targets, target)
+ }
return targets
}
-func stemOf(moduleName string) string {
- // b/139391334: the stem of framework-minus-apex is framework
- // This is hard coded here until we find a good way to query the stem
- // of a module before any other mutators are run
- if moduleName == "framework-minus-apex" {
- return "framework"
- }
- return moduleName
-}
-
var (
bootImageConfigKey = android.NewOnceKey("bootImageConfig")
artBootImageName = "art"
@@ -89,47 +81,34 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
targets := dexpreoptTargets(ctx)
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
- artModules := global.ArtApexJars
+ artModules := global.ArtApexJars.CopyOf()
// With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- artModules = append(artModules, "jacocoagent")
+ artModules.Append("com.android.art", "jacocoagent")
}
- frameworkModules := android.RemoveListFromList(global.BootJars,
- concat(artModules, dexpreopt.GetJarsFromApexJarPairs(global.UpdatableBootJars)))
+ frameworkModules := global.BootJars.CopyOf()
+ frameworkModules.RemoveList(artModules)
artSubdir := "apex/com.android.art/javalib"
frameworkSubdir := "system/framework"
- var artLocations, frameworkLocations []string
- for _, m := range artModules {
- artLocations = append(artLocations, filepath.Join("/"+artSubdir, stemOf(m)+".jar"))
- }
- for _, m := range frameworkModules {
- frameworkLocations = append(frameworkLocations, filepath.Join("/"+frameworkSubdir, stemOf(m)+".jar"))
- }
-
// ART config for the primary boot image in the ART apex.
// It includes the Core Libraries.
artCfg := bootImageConfig{
- extension: false,
- name: artBootImageName,
- stem: "boot",
- installSubdir: artSubdir,
- modules: artModules,
- dexLocations: artLocations,
- dexLocationsDeps: artLocations,
+ name: artBootImageName,
+ stem: "boot",
+ installSubdir: artSubdir,
+ modules: artModules,
}
// Framework config for the boot image extension.
// It includes framework libraries and depends on the ART config.
frameworkCfg := bootImageConfig{
- extension: true,
- name: frameworkBootImageName,
- stem: "boot",
- installSubdir: frameworkSubdir,
- modules: frameworkModules,
- dexLocations: frameworkLocations,
- dexLocationsDeps: append(artLocations, frameworkLocations...),
+ extends: &artCfg,
+ name: frameworkBootImageName,
+ stem: "boot",
+ installSubdir: frameworkSubdir,
+ modules: frameworkModules,
}
configs := map[string]*bootImageConfig{
@@ -143,30 +122,28 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
// expands to <stem>.art for primary image and <stem>-<1st module>.art for extension
- imageName := c.firstModuleNameOrStem() + ".art"
-
- c.imageLocations = []string{c.dir.Join(ctx, c.installSubdir, imageName).String()}
+ imageName := c.firstModuleNameOrStem(ctx) + ".art"
// The path to bootclasspath dex files needs to be known at module
// GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled.
// Set up known paths for them, the singleton rules will copy them there.
// TODO(b/143682396): use module dependencies instead
inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input")
- for _, m := range c.modules {
- c.dexPaths = append(c.dexPaths, inputDir.Join(ctx, stemOf(m)+".jar"))
- }
+ c.dexPaths = c.modules.BuildPaths(ctx, inputDir)
c.dexPathsDeps = c.dexPaths
// Create target-specific variants.
for _, target := range targets {
arch := target.Arch.ArchType
- imageDir := c.dir.Join(ctx, c.installSubdir, arch.String())
+ imageDir := c.dir.Join(ctx, target.Os.String(), c.installSubdir, arch.String())
variant := &bootImageVariant{
bootImageConfig: c,
target: target,
images: imageDir.Join(ctx, imageName),
imagesDeps: c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex"),
+ dexLocations: c.modules.DevicePaths(ctx.Config(), target.Os),
}
+ variant.dexLocationsDeps = variant.dexLocations
c.variants = append(c.variants, variant)
}
@@ -177,8 +154,8 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
for i := range targets {
frameworkCfg.variants[i].primaryImages = artCfg.variants[i].images
+ frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...)
}
- frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
return configs
}).(map[string]*bootImageConfig)
@@ -197,12 +174,9 @@ func defaultBootclasspath(ctx android.PathContext) []string {
global := dexpreopt.GetGlobalConfig(ctx)
image := defaultBootImageConfig(ctx)
- updatableBootclasspath := make([]string, len(global.UpdatableBootJars))
- for i, p := range global.UpdatableBootJars {
- updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(p)
- }
+ updatableBootclasspath := global.UpdatableBootJars.DevicePaths(ctx.Config(), android.Android)
- bootclasspath := append(copyOf(image.dexLocationsDeps), updatableBootclasspath...)
+ bootclasspath := append(copyOf(image.getAnyAndroidVariant().dexLocationsDeps), updatableBootclasspath...)
return bootclasspath
})
}
@@ -217,8 +191,8 @@ func init() {
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
- ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocationsDeps, ":"))
+ ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps, ":"))
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
- ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
+ ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":"))
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 230b1f026..3b192ba55 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -112,13 +112,20 @@ type JavadocProperties struct {
// local files that are used within user customized droiddoc options.
Arg_files []string `android:"path"`
- // user customized droiddoc args.
+ // user customized droiddoc args. Deprecated, use flags instead.
// Available variables for substitution:
//
// $(location <label>): the path to the arg_files with name <label>
// $$: a literal $
Args *string
+ // user customized droiddoc args. Not compatible with property args.
+ // Available variables for substitution:
+ //
+ // $(location <label>): the path to the arg_files with name <label>
+ // $$: a literal $
+ Flags []string
+
// names of the output files used in args that will be generated
Out []string
@@ -191,7 +198,7 @@ type DroiddocProperties struct {
// the generated removed Dex API filename by Doclava.
Removed_dex_api_filename *string
- // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
+ // if set to false, don't allow droiddoc to generate stubs source files. Defaults to false.
Create_stubs *bool
Check_api struct {
@@ -287,6 +294,9 @@ type DroidstubsProperties struct {
// the dirs which Metalava extracts API levels annotations from.
Api_levels_annotations_dirs []string
+ // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
+ Api_levels_jar_filename *string
+
// if set to true, collect the values used by the Dev tools and
// write them in files packaged with the SDK. Defaults to false.
Write_sdk_values *bool
@@ -382,7 +392,7 @@ type Javadoc struct {
argFiles android.Paths
implicits android.Paths
- args string
+ args []string
docZip android.WritablePath
stubsSrcJar android.WritablePath
@@ -440,16 +450,11 @@ func (j *Javadoc) targetSdkVersion() sdkSpec {
func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sdkContext(j))
- if sdkDep.useDefaultLibs {
- ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
- ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
- if sdkDep.hasFrameworkLibs() {
- ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
- }
- } else if sdkDep.useModule {
+ if sdkDep.useModule {
ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
+ ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
}
}
@@ -624,8 +629,8 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
}
srcFiles = filterHtml(srcFiles)
- flags := j.collectAidlFlags(ctx, deps)
- srcFiles = j.genSources(ctx, srcFiles, flags)
+ aidlFlags := j.collectAidlFlags(ctx, deps)
+ srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
// srcs may depend on some genrule output.
j.srcJars = srcFiles.FilterByExt(".srcjar")
@@ -654,24 +659,38 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
}
}
- var err error
- j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
- if strings.HasPrefix(name, "location ") {
- label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
- if paths, ok := argFilesMap[label]; ok {
- return paths, nil
- } else {
- return "", fmt.Errorf("unknown location label %q, expecting one of %q",
- label, strings.Join(argFileLabels, ", "))
+ var argsPropertyName string
+ flags := make([]string, 0)
+ if j.properties.Args != nil && j.properties.Flags != nil {
+ ctx.PropertyErrorf("args", "flags is set. Cannot set args")
+ } else if args := proptools.String(j.properties.Args); args != "" {
+ flags = append(flags, args)
+ argsPropertyName = "args"
+ } else {
+ flags = append(flags, j.properties.Flags...)
+ argsPropertyName = "flags"
+ }
+
+ for _, flag := range flags {
+ args, err := android.Expand(flag, func(name string) (string, error) {
+ if strings.HasPrefix(name, "location ") {
+ label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
+ if paths, ok := argFilesMap[label]; ok {
+ return paths, nil
+ } else {
+ return "", fmt.Errorf("unknown location label %q, expecting one of %q",
+ label, strings.Join(argFileLabels, ", "))
+ }
+ } else if name == "genDir" {
+ return android.PathForModuleGen(ctx).String(), nil
}
- } else if name == "genDir" {
- return android.PathForModuleGen(ctx).String(), nil
- }
- return "", fmt.Errorf("unknown variable '$(%s)'", name)
- })
+ return "", fmt.Errorf("unknown variable '$(%s)'", name)
+ })
- if err != nil {
- ctx.PropertyErrorf("args", "%s", err.Error())
+ if err != nil {
+ ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
+ }
+ j.args = append(j.args, args)
}
return deps
@@ -854,6 +873,10 @@ func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.Rule
}
}
+func (d *Droiddoc) createStubs() bool {
+ return BoolDefault(d.properties.Create_stubs, false)
+}
+
func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
@@ -876,7 +899,7 @@ func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilde
cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
}
- if BoolDefault(d.properties.Create_stubs, true) {
+ if d.createStubs() {
cmd.FlagWithArg("-stubs ", stubsDir.String())
}
@@ -1015,7 +1038,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
d.stubsFlags(ctx, cmd, stubsDir)
- cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
+ cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
if d.properties.Compat_config != nil {
compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
@@ -1058,9 +1081,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule.Build(pctx, ctx, "javadoc", desc)
- if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
- !ctx.Config().IsPdkBuild() {
-
+ if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
@@ -1127,9 +1148,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
}
- if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
- !ctx.Config().IsPdkBuild() {
-
+ if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
@@ -1332,7 +1351,7 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru
cmd.Flag("--include-annotations")
validatingNullability :=
- strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
+ android.InList("--validate-nullability-from-merged-stubs", d.Javadoc.args) ||
String(d.properties.Validate_nullability_from_list) != ""
migratingNullability := String(d.properties.Previous_api) != ""
@@ -1387,38 +1406,41 @@ func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *a
}
func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- if Bool(d.properties.Api_levels_annotations_enabled) {
- d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
+ if !Bool(d.properties.Api_levels_annotations_enabled) {
+ return
+ }
- if len(d.properties.Api_levels_annotations_dirs) == 0 {
- ctx.PropertyErrorf("api_levels_annotations_dirs",
- "has to be non-empty if api levels annotations was enabled!")
- }
+ d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
- cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
- cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
- cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
- cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
-
- ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- for _, dep := range t.deps {
- if strings.HasSuffix(dep.String(), "android.jar") {
- cmd.Implicit(dep)
- }
+ if len(d.properties.Api_levels_annotations_dirs) == 0 {
+ ctx.PropertyErrorf("api_levels_annotations_dirs",
+ "has to be non-empty if api levels annotations was enabled!")
+ }
+
+ cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
+ cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
+ cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
+ cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
+
+ filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
+
+ ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
+ if t, ok := m.(*ExportedDroiddocDir); ok {
+ for _, dep := range t.deps {
+ if strings.HasSuffix(dep.String(), filename) {
+ cmd.Implicit(dep)
}
- cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
- } else {
- ctx.PropertyErrorf("api_levels_annotations_dirs",
- "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
}
- })
-
- }
+ cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/"+filename)
+ } else {
+ ctx.PropertyErrorf("api_levels_annotations_dirs",
+ "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
+ }
+ })
}
func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() && d.apiFile != nil {
+ if Bool(d.properties.Jdiff_enabled) && d.apiFile != nil {
if d.apiFile.String() == "" {
ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
}
@@ -1452,7 +1474,6 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
labels["shallow"] = "true"
}
inputs := []string{android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "metalava.jar").String()}
- inputs = append(inputs, sourcepaths.Strings()...)
if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" {
inputs = append(inputs, strings.Split(v, ",")...)
}
@@ -1504,7 +1525,9 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
cmd.Flag("--no-banner").
Flag("--color").
Flag("--quiet").
- Flag("--format=v2")
+ Flag("--format=v2").
+ FlagWithArg("--repeat-errors-max ", "10").
+ FlagWithArg("--hide ", "UnresolvedImport")
return cmd
}
@@ -1545,14 +1568,14 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
d.apiLevelsAnnotationsFlags(ctx, cmd)
d.apiToXmlFlags(ctx, cmd)
- if strings.Contains(d.Javadoc.args, "--generate-documentation") {
+ if android.InList("--generate-documentation", d.Javadoc.args) {
// Currently Metalava have the ability to invoke Javadoc in a seperate process.
// Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
// "--generate-documentation" arg. This is not needed when Metalava removes this feature.
- d.Javadoc.args = d.Javadoc.args + " -nodocs "
+ d.Javadoc.args = append(d.Javadoc.args, "-nodocs")
}
- cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
+ cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
for _, o := range d.Javadoc.properties.Out {
cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
}
@@ -1565,7 +1588,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Add API lint options.
- if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
+ if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) {
doApiLint = true
newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
@@ -1632,8 +1655,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Add "check released" options. (Detect incompatible API changes from the last public release)
- if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
- !ctx.Config().IsPdkBuild() {
+ if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
doCheckReleased = true
if len(d.Javadoc.properties.Out) > 0 {
@@ -1666,7 +1688,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
impRule := android.NewRuleBuilder()
impCmd := impRule.Command()
- // A dummy action that copies the ninja generated rsp file to a new location. This allows us to
+ // An action that copies the ninja generated rsp file to a new location. This allows us to
// add a large number of inputs to a file without exceeding bash command length limits (which
// would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
// rsp file to be ${output}.rsp.
@@ -1710,8 +1732,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule.Build(pctx, ctx, "metalava", "metalava merged")
- if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
- !ctx.Config().IsPdkBuild() {
+ if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
if len(d.Javadoc.properties.Out) > 0 {
ctx.PropertyErrorf("out", "out property may not be combined with check_api")
@@ -1825,7 +1846,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
}
- if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
+ if Bool(d.properties.Jdiff_enabled) {
if len(d.Javadoc.properties.Out) > 0 {
ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
}
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index b5a021785..63b801a5c 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -23,8 +23,8 @@ import (
)
var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{
- Command: "${config.Class2Greylist} --stub-api-flags ${stubAPIFlags} $in $outFlag $out",
- CommandDeps: []string{"${config.Class2Greylist}"},
+ Command: "${config.Class2NonSdkList} --stub-api-flags ${stubAPIFlags} $in $outFlag $out",
+ CommandDeps: []string{"${config.Class2NonSdkList}"},
}, "outFlag", "stubAPIFlags")
type hiddenAPI struct {
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 95dd0bb09..29b6bcd7d 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -43,7 +43,7 @@ func hiddenAPISingletonPaths(ctx android.PathContext) hiddenAPISingletonPathsStr
return hiddenAPISingletonPathsStruct{
flags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-flags.csv"),
index: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-index.csv"),
- metadata: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-greylist.csv"),
+ metadata: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-unsupported.csv"),
stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
}
}).(hiddenAPISingletonPathsStruct)
@@ -100,7 +100,7 @@ func stubFlagsRule(ctx android.SingletonContext) {
// Add the android.test.base to the set of stubs only if the android.test.base module is on
// the boot jars list as the runtime will only enforce hiddenapi access against modules on
// that list.
- if inList("android.test.base", ctx.Config().BootJars()) && !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ if inList("android.test.base", ctx.Config().BootJars()) && !ctx.Config().AlwaysUsePrebuiltSdks() {
publicStubModules = append(publicStubModules, "android.test.base.stubs")
}
@@ -116,7 +116,7 @@ func stubFlagsRule(ctx android.SingletonContext) {
// Core Platform API stubs
corePlatformStubModules := []string{
- "core.platform.api.stubs",
+ "legacy.core.platform.api.stubs",
}
// Allow products to define their own stubs for custom product jars that apps can use.
@@ -147,7 +147,7 @@ func stubFlagsRule(ctx android.SingletonContext) {
name := ctx.ModuleName(module)
for moduleList, pathList := range moduleListToPathList {
if i := android.IndexList(name, *moduleList); i != -1 {
- pathList[i] = j.DexJar()
+ pathList[i] = j.DexJarBuildPath()
}
}
}
@@ -217,7 +217,7 @@ func moduleForGreyListRemovedApis(ctx android.SingletonContext, module android.M
}
// flagsRule creates a rule to build hiddenapi-flags.csv out of flags.csv files generated for boot image modules and
-// the greylists.
+// the unsupported API.
func flagsRule(ctx android.SingletonContext) android.Path {
var flagsCSV android.Paths
var greylistRemovedApis android.Paths
@@ -256,19 +256,19 @@ func flagsRule(ctx android.SingletonContext) android.Path {
Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py")).
FlagWithInput("--csv ", stubFlags).
Inputs(flagsCSV).
- FlagWithInput("--greylist ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist.txt")).
- FlagWithInput("--greylist-ignore-conflicts ", combinedRemovedApis).
- FlagWithInput("--greylist-max-q ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-q.txt")).
- FlagWithInput("--greylist-max-p ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-p.txt")).
- FlagWithInput("--greylist-max-o-ignore-conflicts ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-o.txt")).
- FlagWithInput("--blacklist ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-force-blacklist.txt")).
- FlagWithInput("--greylist-packages ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-packages.txt")).
+ FlagWithInput("--unsupported ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-unsupported.txt")).
+ FlagWithInput("--unsupported-ignore-conflicts ", combinedRemovedApis).
+ FlagWithInput("--max-target-q ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-max-target-q.txt")).
+ FlagWithInput("--max-target-p ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-max-target-p.txt")).
+ FlagWithInput("--max-target-o-ignore-conflicts ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-max-target-o.txt")).
+ FlagWithInput("--blocked ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-force-blocked.txt")).
+ FlagWithInput("--unsupported-packages ",
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-unsupported-packages.txt")).
FlagWithOutput("--output ", tempPath)
commitChangeForRestat(rule, tempPath, outputPath)
@@ -293,7 +293,7 @@ func emptyFlagsRule(ctx android.SingletonContext) android.Path {
return outputPath
}
-// metadataRule creates a rule to build hiddenapi-greylist.csv out of the metadata.csv files generated for boot image
+// metadataRule creates a rule to build hiddenapi-unsupported.csv out of the metadata.csv files generated for boot image
// modules.
func metadataRule(ctx android.SingletonContext) android.Path {
var metadataCSV android.Paths
diff --git a/java/java.go b/java/java.go
index 0a764e636..ecc2e2aaf 100644
--- a/java/java.go
+++ b/java/java.go
@@ -29,6 +29,7 @@ import (
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java/config"
"android/soong/tradefed"
)
@@ -44,7 +45,7 @@ func init() {
PropertyName: "java_libs",
},
func(j *Library) android.Path {
- implementationJars := j.ImplementationJars()
+ implementationJars := j.ImplementationAndResourcesJars()
if len(implementationJars) != 1 {
panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
}
@@ -140,10 +141,15 @@ func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
// Findbugs
type CompilerProperties struct {
- // list of source files used to compile the Java module. May be .java, .logtags, .proto,
+ // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto,
// or .aidl files.
Srcs []string `android:"path,arch_variant"`
+ // list Kotlin of source files containing Kotlin code that should be treated as common code in
+ // a codebase that supports Kotlin multiplatform. See
+ // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files.
+ Common_srcs []string `android:"path,arch_variant"`
+
// list of source files that should not be used to build the Java module.
// This is most useful in the arch/multilib variants to remove non-common files
Exclude_srcs []string `android:"path,arch_variant"`
@@ -259,9 +265,6 @@ type CompilerProperties struct {
}
type CompilerDeviceProperties struct {
- // list of module-specific flags that will be used for dex compiles
- Dxflags []string `android:"arch_variant"`
-
// if not blank, set to the version of the sdk to compile against.
// Defaults to compiling against the current platform.
Sdk_version *string
@@ -307,37 +310,6 @@ type CompilerDeviceProperties struct {
}
}
- // If set to true, compile dex regardless of installable. Defaults to false.
- Compile_dex *bool
-
- Optimize struct {
- // If false, disable all optimization. Defaults to true for android_app and android_test
- // modules, false for java_library and java_test modules.
- Enabled *bool
- // True if the module containing this has it set by default.
- EnabledByDefault bool `blueprint:"mutated"`
-
- // If true, optimize for size by removing unused code. Defaults to true for apps,
- // false for libraries and tests.
- Shrink *bool
-
- // If true, optimize bytecode. Defaults to false.
- Optimize *bool
-
- // If true, obfuscate bytecode. Defaults to false.
- Obfuscate *bool
-
- // If true, do not use the flag files generated by aapt that automatically keep
- // classes referenced by the app manifest. Defaults to false.
- No_aapt_flags *bool
-
- // Flags to pass to proguard.
- Proguard_flags []string
-
- // Specifies the locations of files containing proguard flags.
- Proguard_flags_files []string `android:"path"`
- }
-
// When targeting 1.9 and above, override the modules to use with --system,
// otherwise provides defaults libraries to add to the bootclasspath.
System_modules *string
@@ -351,12 +323,6 @@ type CompilerDeviceProperties struct {
// set the name of the output
Stem *string
- // Keep the data uncompressed. We always need uncompressed dex for execution,
- // so this might actually save space by avoiding storing the same data twice.
- // This defaults to reasonable value based on module and should not be set.
- // It exists only to support ART tests.
- Uncompress_dex *bool
-
IsSDKLibrary bool `blueprint:"mutated"`
// If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
@@ -364,10 +330,6 @@ type CompilerDeviceProperties struct {
V4_signature *bool
}
-func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
- return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault)
-}
-
// Functionality common to Module and Import
//
// It is embedded in Module so its functionality can be used by methods in Module
@@ -436,9 +398,6 @@ type Module struct {
// output file containing uninstrumented classes that will be instrumented by jacoco
jacocoReportClassesFile android.Path
- // output file containing mapping of obfuscated names
- proguardDictionary android.Path
-
// output file of the module, which may be a classes jar or a dex jar
outputFile android.Path
extraOutputFiles android.Paths
@@ -454,14 +413,11 @@ type Module struct {
compiledJavaSrcs android.Paths
compiledSrcJars android.Paths
- // list of extra progurad flag files
- extraProguardFlagFiles android.Paths
-
// manifest file to use instead of properties.Manifest
overrideManifest android.OptionalPath
- // list of SDK lib names that this java module is exporting
- exportedSdkLibs []string
+ // map of SDK libs exported by this java module to their build and install paths
+ exportedSdkLibs dexpreopt.LibraryPaths
// list of plugins that this java module is exporting
exportedPluginJars android.Paths
@@ -483,13 +439,17 @@ type Module struct {
extraResources android.Paths
hiddenAPI
+ dexer
dexpreopter
linter
// list of the xref extraction files
kytheFiles android.Paths
- distFile android.Path
+ distFiles android.TaggedDistFiles
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
func (j *Module) addHostProperties() {
@@ -503,6 +463,7 @@ func (j *Module) addHostAndDeviceProperties() {
j.addHostProperties()
j.AddProperties(
&j.deviceProperties,
+ &j.dexer.dexProperties,
&j.dexpreoptProperties,
&j.linter.properties,
)
@@ -515,7 +476,10 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) {
case ".jar":
return android.Paths{j.implementationAndResourcesJar}, nil
case ".proguard_map":
- return android.Paths{j.proguardDictionary}, nil
+ if j.dexer.proguardDictionary.Valid() {
+ return android.Paths{j.dexer.proguardDictionary.Path()}, nil
+ }
+ return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -529,13 +493,19 @@ type ApexDependency interface {
ImplementationAndResourcesJars() android.Paths
}
+// Provides build path and install path to DEX jars.
+type UsesLibraryDependency interface {
+ DexJarBuildPath() android.Path
+ DexJarInstallPath() android.Path
+}
+
type Dependency interface {
ApexDependency
+ UsesLibraryDependency
ImplementationJars() android.Paths
ResourceJars() android.Paths
- DexJar() android.Path
AidlIncludeDirs() android.Paths
- ExportedSdkLibs() []string
+ ExportedSdkLibs() dexpreopt.LibraryPaths
ExportedPlugins() (android.Paths, []string)
SrcJarArgs() ([]string, android.Paths)
BaseModuleName() string
@@ -551,7 +521,20 @@ func (j *Module) XrefJavaFiles() android.Paths {
}
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
- android.InitAndroidArchModule(module, hod, android.MultilibCommon)
+ initJavaModule(module, hod, false)
+}
+
+func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
+ initJavaModule(module, hod, true)
+}
+
+func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
+ multilib := android.MultilibCommon
+ if multiTargets {
+ android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
+ } else {
+ android.InitAndroidArchModule(module, hod, multilib)
+ }
android.InitDefaultableModule(module)
}
@@ -570,6 +553,7 @@ func IsJniDepTag(depTag blueprint.DependencyTag) bool {
}
var (
+ dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
staticLibTag = dependencyTag{name: "staticlib"}
libTag = dependencyTag{name: "javalib"}
java9LibTag = dependencyTag{name: "java9lib"}
@@ -578,7 +562,6 @@ var (
bootClasspathTag = dependencyTag{name: "bootclasspath"}
systemModulesTag = dependencyTag{name: "system modules"}
frameworkResTag = dependencyTag{name: "framework-res"}
- frameworkApkTag = dependencyTag{name: "framework-apk"}
kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"}
proguardRaiseTag = dependencyTag{name: "proguard-raise"}
@@ -597,7 +580,7 @@ func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
}
type sdkDep struct {
- useModule, useFiles, useDefaultLibs, invalidVersion bool
+ useModule, useFiles, invalidVersion bool
// The modules that will be added to the bootclasspath when targeting 1.8 or lower
bootclasspath []string
@@ -606,7 +589,11 @@ type sdkDep struct {
// modules are to be used.
systemModules string
+ // The modules that will be added to the classpath regardless of the Java language level targeted
+ classpath []string
+
// The modules that will be added ot the classpath when targeting 1.9 or higher
+ // (normally these will be on the bootclasspath when targeting 1.8 or lower)
java9Classpath []string
frameworkResModule string
@@ -645,6 +632,21 @@ func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
ctx.Config().UnbundledBuild())
}
+func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
+ // Force enable the instrumentation for java code that is built for APEXes ...
+ // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
+ // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
+ isJacocoAgent := ctx.ModuleName() == "jacocoagent"
+ if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+ if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+ return true
+ } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ return true
+ }
+ }
+ return false
+}
+
func (j *Module) sdkVersion() sdkSpec {
return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
}
@@ -681,34 +683,29 @@ func (j *Module) AvailableFor(what string) bool {
return j.ApexModuleBase.AvailableFor(what)
}
+func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext sdkContext, d dexer) {
+ sdkDep := decodeSdkDep(ctx, sdkContext)
+ if sdkDep.useModule {
+ ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
+ ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
+ ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
+ if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
+ ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...)
+ }
+ if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() {
+ ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...)
+ }
+ }
+ if sdkDep.systemModules != "" {
+ ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
+ }
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
j.linter.deps(ctx)
- sdkDep := decodeSdkDep(ctx, sdkContext(j))
- if sdkDep.useDefaultLibs {
- ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
- ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
- if sdkDep.hasFrameworkLibs() {
- ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
- }
- } else if sdkDep.useModule {
- ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
- ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
- if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
- ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
- ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
- }
- }
- if sdkDep.systemModules != "" {
- ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
- }
-
- if ctx.ModuleName() == "android_stubs_current" ||
- ctx.ModuleName() == "android_system_stubs_current" ||
- ctx.ModuleName() == "android_test_stubs_current" {
- ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
- }
+ sdkDeps(ctx, sdkContext(j), j.dexer)
}
syspropPublicStubs := syspropPublicStubs(ctx.Config())
@@ -875,8 +872,9 @@ type linkTypeContext interface {
func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
switch name {
- case "core.current.stubs", "core.platform.api.stubs", "stub-annotations",
- "private-stub-annotations-jar", "core-lambda-stubs", "core-generated-annotation-stubs":
+ case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs",
+ "stub-annotations", "private-stub-annotations-jar",
+ "core-lambda-stubs", "core-generated-annotation-stubs":
return javaCore, true
case "android_stubs_current":
return javaSdk, true
@@ -982,12 +980,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
}
- // If this is a component library (stubs, etc.) for a java_sdk_library then
- // add the name of that java_sdk_library to the exported sdk libs to make sure
- // that, if necessary, a <uses-library> element for that java_sdk_library is
- // added to the Android manifest.
- j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
-
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -1007,7 +999,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...)
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, dep.OptionalImplicitSdkLibrary(), dep.DexJarBuildPath(), dep.DexJarInstallPath())
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
@@ -1018,7 +1010,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case libTag, instrumentationForTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
// sdk lib names from dependencies are re-exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+ j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs())
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses := dep.ExportedPlugins()
addPlugins(&deps, pluginJars, pluginClasses...)
@@ -1030,7 +1022,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
// sdk lib names from dependencies are re-exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+ j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs())
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses := dep.ExportedPlugins()
addPlugins(&deps, pluginJars, pluginClasses...)
@@ -1057,18 +1049,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
} else {
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
- case frameworkApkTag:
- if ctx.ModuleName() == "android_stubs_current" ||
- ctx.ModuleName() == "android_system_stubs_current" ||
- ctx.ModuleName() == "android_test_stubs_current" {
- // framework stubs.jar need to depend on framework-res.apk, in order to pull the
- // resource files out of there for aapt.
- //
- // Normally the package rule runs aapt, which includes the resource,
- // but we're not running that in our package rule so just copy in the
- // resource files here.
- deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
- }
case kotlinStdlibTag:
deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...)
case kotlinAnnotationsTag:
@@ -1105,8 +1085,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
})
- j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
-
return deps
}
@@ -1186,9 +1164,9 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
if flags.javaVersion.usesJavaModules() {
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
}
- if ctx.Config().MinimizeJavaDebugInfo() {
- // Override the -g flag passed globally to remove local variable debug info to reduce
- // disk and memory usage.
+ if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
+ // For non-host binaries, override the -g flag passed globally to remove
+ // local variable debug info to reduce disk and memory usage.
javacFlags = append(javacFlags, "-g:source,lines")
}
javacFlags = append(javacFlags, "-Xlint:-dep-ann")
@@ -1284,6 +1262,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
}
+ kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
+ if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
+ ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
+ }
+
srcFiles = j.genSources(ctx, srcFiles, flags)
srcJars := srcFiles.FilterByExt(".srcjar")
@@ -1337,6 +1320,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Collect .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
+ j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
@@ -1348,7 +1332,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Use kapt for annotation processing
kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
- kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, srcJars, flags)
+ kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
srcJars = append(srcJars, kaptSrcJar)
kotlinJars = append(kotlinJars, kaptResJar)
// Disable annotation processing in javac, it's already been handled by kapt
@@ -1357,7 +1341,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
}
kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
- kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags)
+ kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
if ctx.Failed() {
return
}
@@ -1583,11 +1567,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.headerJarFile = j.implementationJarFile
}
- // Force enable the instrumentation for java code that is built for APEXes ...
- // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
- // doesn't make sense)
- isJacocoAgent := ctx.ModuleName() == "jacocoagent"
- if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+ if j.shouldInstrumentInApex(ctx) {
j.properties.Instrument = true
}
@@ -1609,8 +1589,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Enable dex compilation for the APEX variants, unless it is disabled explicitly
if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() {
- if j.deviceProperties.Compile_dex == nil {
- j.deviceProperties.Compile_dex = proptools.BoolPtr(true)
+ if j.dexProperties.Compile_dex == nil {
+ j.dexProperties.Compile_dex = proptools.BoolPtr(true)
}
if j.deviceProperties.Hostdex == nil {
j.deviceProperties.Hostdex = proptools.BoolPtr(true)
@@ -1618,10 +1598,14 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
}
if ctx.Device() && j.hasCode(ctx) &&
- (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
+ (Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) {
+ if j.shouldInstrumentStatic(ctx) {
+ j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
+ android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
+ }
// Dex compilation
var dexOutputFile android.ModuleOutPath
- dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
+ dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName)
if ctx.Failed() {
return
}
@@ -1631,7 +1615,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Hidden API CSV generation and dex encoding
dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile,
- proptools.Bool(j.deviceProperties.Uncompress_dex))
+ proptools.Bool(j.dexProperties.Uncompress_dex))
// merge dex jar with resources if necessary
if j.resourceJar != nil {
@@ -1639,7 +1623,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
false, nil, nil)
- if *j.deviceProperties.Uncompress_dex {
+ if *j.dexProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
dexOutputFile = combinedAlignedJar
@@ -1683,6 +1667,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
+ if j.ApexVariationName() != "" && ctx.Config().UnbundledBuildApps() {
+ j.linter.buildModuleReportZip = true
+ }
j.linter.lint(ctx)
}
@@ -1811,10 +1798,14 @@ func (j *Module) ImplementationJars() android.Paths {
return android.Paths{j.implementationJarFile}
}
-func (j *Module) DexJar() android.Path {
+func (j *Module) DexJarBuildPath() android.Path {
return j.dexJarFile
}
+func (j *Module) DexJarInstallPath() android.Path {
+ return j.installFile
+}
+
func (j *Module) ResourceJars() android.Paths {
if j.resourceJar == nil {
return nil
@@ -1834,8 +1825,7 @@ func (j *Module) AidlIncludeDirs() android.Paths {
return j.exportAidlIncludeDirs
}
-func (j *Module) ExportedSdkLibs() []string {
- // exportedSdkLibs is type []string
+func (j *Module) ExportedSdkLibs() dexpreopt.LibraryPaths {
return j.exportedSdkLibs
}
@@ -1862,6 +1852,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
}
+ dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
}
func (j *Module) CompilerDeps() []string {
@@ -1880,6 +1871,24 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return j.depIsInSameApex(ctx, dep)
}
+func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ sdkSpec := j.minSdkVersion()
+ if !sdkSpec.specified() {
+ return fmt.Errorf("min_sdk_version is not specified")
+ }
+ if sdkSpec.kind == sdkCore {
+ return nil
+ }
+ ver, err := sdkSpec.effectiveVersion(ctx)
+ if err != nil {
+ return err
+ }
+ if int(ver) > sdkVersion {
+ return fmt.Errorf("newer SDK(%v)", ver)
+ }
+ return nil
+}
+
func (j *Module) Stem() string {
return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
}
@@ -1900,18 +1909,9 @@ func (j *Module) IsInstallable() bool {
// Java libraries (.jar file)
//
-type LibraryProperties struct {
- Dist struct {
- // The tag of the output of this module that should be output.
- Tag *string `android:"arch_variant"`
- } `android:"arch_variant"`
-}
-
type Library struct {
Module
- libraryProperties LibraryProperties
-
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
}
@@ -1953,13 +1953,17 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.checkSdkVersions(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- if j.deviceProperties.Uncompress_dex == nil {
+ if j.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
- j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
+ j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
}
- j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex
+ j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
+ j.exportedSdkLibs = make(dexpreopt.LibraryPaths)
j.compile(ctx, nil)
+ // Collect the module directory for IDE info in java/jdeps.go.
+ j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
+
exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
var extraInstallDeps android.Paths
@@ -1970,14 +1974,13 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
- // Verify Dist.Tag is set to a supported output
- if j.libraryProperties.Dist.Tag != nil {
- distFiles, err := j.OutputFiles(*j.libraryProperties.Dist.Tag)
- if err != nil {
- ctx.PropertyErrorf("dist.tag", "%s", err.Error())
- }
- j.distFile = distFiles[0]
- }
+ // If this is a component library (stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), j.DexJarBuildPath(), j.DexJarInstallPath())
+
+ j.distFiles = j.GenerateTaggedDistFiles(ctx)
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -2095,7 +2098,6 @@ func LibraryFactory() android.Module {
module := &Library{}
module.addHostAndDeviceProperties()
- module.AddProperties(&module.libraryProperties)
module.initModuleAndImport(&module.ModuleBase)
@@ -2130,6 +2132,12 @@ func LibraryHostFactory() android.Module {
// Java Tests
//
+// Test option struct.
+type TestOptions struct {
+ // a list of extra test configuration files that should be installed with the module.
+ Extra_test_configs []string `android:"path,arch_variant"`
+}
+
type testProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
@@ -2155,6 +2163,14 @@ type testProperties struct {
// Add parameterized mainline modules to auto generated test config. The options will be
// handled by TradeFed to do downloading and installing the specified modules on the device.
Test_mainline_modules []string
+
+ // Test options.
+ Test_options TestOptions
+}
+
+type hostTestProperties struct {
+ // list of native binary modules that should be installed alongside the test
+ Data_native_bins []string `android:"arch_variant"`
}
type testHelperLibraryProperties struct {
@@ -2178,8 +2194,15 @@ type Test struct {
testProperties testProperties
- testConfig android.Path
- data android.Paths
+ testConfig android.Path
+ extraTestConfigs android.Paths
+ data android.Paths
+}
+
+type TestHost struct {
+ Test
+
+ testHostProperties hostTestProperties
}
type TestHelperLibrary struct {
@@ -2194,13 +2217,31 @@ type JavaTestImport struct {
prebuiltTestProperties prebuiltTestProperties
testConfig android.Path
+ dexJarFile android.Path
+}
+
+func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(j.testHostProperties.Data_native_bins) > 0 {
+ for _, target := range ctx.MultiTargets() {
+ ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
+ }
+ }
+
+ j.deps(ctx)
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
+
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
+ j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
+
+ ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+ j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
+ })
+
j.Library.GenerateAndroidBuildActions(ctx)
}
@@ -2341,14 +2382,15 @@ func JavaTestImportFactory() android.Module {
// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
// compiled against the host bootclasspath.
func TestHostFactory() android.Module {
- module := &Test{}
+ module := &TestHost{}
module.addHostProperties()
module.AddProperties(&module.testProperties)
+ module.AddProperties(&module.testHostProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
- InitJavaModule(module, android.HostSupported)
+ InitJavaModuleMultiTargets(module, android.HostSupported)
return module
}
@@ -2480,6 +2522,12 @@ type ImportProperties struct {
// set the name of the output
Stem *string
+
+ Aidl struct {
+ // directories that should be added as include directories for any aidl sources of modules
+ // that depend on this module, as well as to aidl for this module.
+ Export_include_dirs []string
+ }
}
type Import struct {
@@ -2492,20 +2540,39 @@ type Import struct {
// Functionality common to Module and Import.
embeddableInModuleAndImport
+ hiddenAPI
+ dexer
+
properties ImportProperties
+ // output file containing classes.dex and resources
+ dexJarFile android.Path
+
combinedClasspathFile android.Path
- exportedSdkLibs []string
+ exportedSdkLibs dexpreopt.LibraryPaths
+ exportAidlIncludeDirs android.Paths
}
func (j *Import) sdkVersion() sdkSpec {
return sdkSpecFrom(String(j.properties.Sdk_version))
}
+func (j *Import) makeSdkVersion() string {
+ return j.sdkVersion().raw
+}
+
+func (j *Import) systemModules() string {
+ return "none"
+}
+
func (j *Import) minSdkVersion() sdkSpec {
return j.sdkVersion()
}
+func (j *Import) targetSdkVersion() sdkSpec {
+ return j.sdkVersion()
+}
+
func (j *Import) MinSdkVersion() string {
return j.minSdkVersion().version.String()
}
@@ -2532,6 +2599,10 @@ func (a *Import) JacocoReportClassesFile() android.Path {
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
+
+ if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
+ sdkDeps(ctx, sdkContext(j), j.dexer)
+ }
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2547,12 +2618,9 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
TransformJetifier(ctx, outputFile, inputFile)
}
j.combinedClasspathFile = outputFile
+ j.exportedSdkLibs = make(dexpreopt.LibraryPaths)
- // If this is a component library (impl, stubs, etc.) for a java_sdk_library then
- // add the name of that java_sdk_library to the exported sdk libs to make sure
- // that, if necessary, a <uses-library> element for that java_sdk_library is
- // added to the Android manifest.
- j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
+ var flags javaBuilderFlags
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
@@ -2562,23 +2630,55 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case Dependency:
switch tag {
case libTag, staticLibTag:
+ flags.classpath = append(flags.classpath, dep.HeaderJars()...)
// sdk lib names from dependencies are re-exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+ j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs())
+ case bootClasspathTag:
+ flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...)
}
case SdkLibraryDependency:
switch tag {
case libTag:
+ flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
+ j.exportedSdkLibs.AddLibraryPath(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath())
}
}
})
- j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
+ var installFile android.Path
if Bool(j.properties.Installable) {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+ installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
jarName, outputFile)
}
+
+ // If this is a component library (impl, stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), outputFile, installFile)
+
+ j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
+
+ if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ if sdkDep.invalidVersion {
+ ctx.AddMissingDependencies(sdkDep.bootclasspath)
+ ctx.AddMissingDependencies(sdkDep.java9Classpath)
+ } else if sdkDep.useFiles {
+ // sdkDep.jar is actually equivalent to turbine header.jar.
+ flags.classpath = append(flags.classpath, sdkDep.jars...)
+ }
+
+ // Dex compilation
+ var dexOutputFile android.ModuleOutPath
+ dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName)
+ if ctx.Failed() {
+ return
+ }
+
+ j.dexJarFile = dexOutputFile
+ }
}
var _ Dependency = (*Import)(nil)
@@ -2608,15 +2708,19 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths {
return android.Paths{j.combinedClasspathFile}
}
-func (j *Import) DexJar() android.Path {
+func (j *Import) DexJarBuildPath() android.Path {
+ return j.dexJarFile
+}
+
+func (j *Import) DexJarInstallPath() android.Path {
return nil
}
func (j *Import) AidlIncludeDirs() android.Paths {
- return nil
+ return j.exportAidlIncludeDirs
}
-func (j *Import) ExportedSdkLibs() []string {
+func (j *Import) ExportedSdkLibs() dexpreopt.LibraryPaths {
return j.exportedSdkLibs
}
@@ -2632,6 +2736,11 @@ func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return j.depIsInSameApex(ctx, dep)
}
+func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ // Do not check for prebuilts against the min_sdk_version of enclosing APEX
+ return nil
+}
+
// Add compile time check for interface implementation
var _ android.IDEInfo = (*Import)(nil)
var _ android.IDECustomizedModuleName = (*Import)(nil)
@@ -2668,10 +2777,15 @@ var _ android.PrebuiltInterface = (*Import)(nil)
func ImportFactory() android.Module {
module := &Import{}
- module.AddProperties(&module.properties)
+ module.AddProperties(
+ &module.properties,
+ &module.dexer.dexProperties,
+ )
module.initModuleAndImport(&module.ModuleBase)
+ module.dexProperties.Optimize.EnabledByDefault = false
+
android.InitPrebuiltModule(module, &module.properties.Jars)
android.InitApexModule(module)
android.InitSdkAwareModule(module)
@@ -2738,6 +2852,10 @@ func (a *DexImport) JacocoReportClassesFile() android.Path {
return nil
}
+func (a *DexImport) LintDepSets() LintDepSets {
+ return LintDepSets{}
+}
+
func (j *DexImport) IsInstallable() bool {
return true
}
@@ -2797,10 +2915,15 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
}
-func (j *DexImport) DexJar() android.Path {
+func (j *DexImport) DexJarBuildPath() android.Path {
return j.dexJarFile
}
+func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ // we don't check prebuilt modules for sdk_version
+ return nil
+}
+
// dex_import imports a `.jar` file containing classes.dex files.
//
// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
@@ -2866,6 +2989,7 @@ func DefaultsFactory() android.Module {
module.AddProperties(
&CompilerProperties{},
&CompilerDeviceProperties{},
+ &DexProperties{},
&DexpreoptProperties{},
&android.ProtoProperties{},
&aaptProperties{},
@@ -2873,6 +2997,7 @@ func DefaultsFactory() android.Module {
&appProperties{},
&appTestProperties{},
&overridableAppProperties{},
+ &testProperties{},
&ImportProperties{},
&AARImportProperties{},
&sdkLibraryProperties{},
diff --git a/java/java_test.go b/java/java_test.go
index f0de52fb9..3f7bab194 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -20,7 +20,6 @@ import (
"path/filepath"
"reflect"
"regexp"
- "sort"
"strconv"
"strings"
"testing"
@@ -31,6 +30,7 @@ import (
"android/soong/cc"
"android/soong/dexpreopt"
"android/soong/genrule"
+ "android/soong/python"
)
var buildDir string
@@ -81,17 +81,22 @@ func testContext() *android.TestContext {
ctx.RegisterModuleType("java_plugin", PluginFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+ ctx.RegisterModuleType("python_binary_host", python.PythonBinaryHostFactory)
RegisterDocsBuildComponents(ctx)
RegisterStubsBuildComponents(ctx)
RegisterSdkLibraryBuildComponents(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ ctx.PreArchMutators(android.RegisterComponentsMutator)
RegisterPrebuiltApisBuildComponents(ctx)
+ ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators)
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
+ android.RegisterPrebuiltMutators(ctx)
+
// Register module types and mutators from cc needed for JNI testing
cc.RegisterRequiredBuildComponentsForTest(ctx)
@@ -466,7 +471,41 @@ func TestBinary(t *testing.T) {
t.Errorf("expected binary wrapper implicits [%q], got %v",
barJar, barWrapperDeps)
}
+}
+
+func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) {
+ bp := `
+ java_library {
+ name: "target_library",
+ srcs: ["a.java"],
+ }
+
+ java_binary_host {
+ name: "host_binary",
+ srcs: ["b.java"],
+ }
+ `
+ config := testConfig(nil, bp, nil)
+ config.TestProductVariables.MinimizeJavaDebugInfo = proptools.BoolPtr(true)
+
+ ctx, _ := testJavaWithConfig(t, config)
+ // first, check that the -g flag is added to target modules
+ targetLibrary := ctx.ModuleForTests("target_library", "android_common")
+ targetJavaFlags := targetLibrary.Module().VariablesForTests()["javacFlags"]
+ if !strings.Contains(targetJavaFlags, "-g:source,lines") {
+ t.Errorf("target library javac flags %v should contain "+
+ "-g:source,lines override with MinimizeJavaDebugInfo", targetJavaFlags)
+ }
+
+ // check that -g is not overridden for host modules
+ buildOS := android.BuildOs.String()
+ hostBinary := ctx.ModuleForTests("host_binary", buildOS+"_common")
+ hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
+ if strings.Contains(hostJavaFlags, "-g:source,lines") {
+ t.Errorf("java_binary_host javac flags %v should not have "+
+ "-g:source,lines override with MinimizeJavaDebugInfo", hostJavaFlags)
+ }
}
func TestPrebuilts(t *testing.T) {
@@ -486,6 +525,8 @@ func TestPrebuilts(t *testing.T) {
java_import {
name: "baz",
jars: ["b.jar"],
+ sdk_version: "current",
+ compile_dex: true,
}
dex_import {
@@ -516,8 +557,10 @@ func TestPrebuilts(t *testing.T) {
fooModule := ctx.ModuleForTests("foo", "android_common")
javac := fooModule.Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
- barJar := ctx.ModuleForTests("bar", "android_common").Rule("combineJar").Output
- bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
+ barModule := ctx.ModuleForTests("bar", "android_common")
+ barJar := barModule.Rule("combineJar").Output
+ bazModule := ctx.ModuleForTests("baz", "android_common")
+ bazJar := bazModule.Rule("combineJar").Output
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
fooLibrary := fooModule.Module().(*Library)
@@ -532,6 +575,11 @@ func TestPrebuilts(t *testing.T) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
}
+ barDexJar := barModule.Module().(*Import).DexJarBuildPath()
+ if barDexJar != nil {
+ t.Errorf("bar dex jar build path expected to be nil, got %q", barDexJar)
+ }
+
if !strings.Contains(javac.Args["classpath"], sdklibStubsJar.String()) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
}
@@ -540,6 +588,12 @@ func TestPrebuilts(t *testing.T) {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
}
+ bazDexJar := bazModule.Module().(*Import).DexJarBuildPath().String()
+ expectedDexJar := buildDir + "/.intermediates/baz/android_common/dex/baz.jar"
+ if bazDexJar != expectedDexJar {
+ t.Errorf("baz dex jar build path expected %q, got %q", expectedDexJar, bazDexJar)
+ }
+
ctx.ModuleForTests("qux", "android_common").Rule("Cp")
}
@@ -596,6 +650,89 @@ func TestJavaSdkLibraryImport(t *testing.T) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], sdklibStubsJar.String())
}
}
+
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ `prebuilt_sdklib.stubs`,
+ `prebuilt_sdklib.stubs.source.test`,
+ `prebuilt_sdklib.stubs.system`,
+ `prebuilt_sdklib.stubs.test`,
+ })
+}
+
+func TestJavaSdkLibraryImport_WithSource(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library_import {
+ name: "sdklib",
+ public: {
+ jars: ["a.jar"],
+ },
+ }
+ `)
+
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ `dex2oatd`,
+ `prebuilt_sdklib`,
+ `sdklib.impl`,
+ `sdklib.stubs`,
+ `sdklib.stubs.source`,
+ `sdklib.xml`,
+ })
+
+ CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
+ `prebuilt_sdklib.stubs`,
+ `sdklib.impl`,
+ // This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
+ // dependency is added after prebuilts may have been renamed and so has to use
+ // the renamed name.
+ `sdklib.xml`,
+ })
+}
+
+func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library_import {
+ name: "sdklib",
+ prefer: true,
+ public: {
+ jars: ["a.jar"],
+ },
+ }
+ `)
+
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ `dex2oatd`,
+ `prebuilt_sdklib`,
+ `sdklib.impl`,
+ `sdklib.stubs`,
+ `sdklib.stubs.source`,
+ `sdklib.xml`,
+ })
+
+ CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
+ `prebuilt_sdklib.stubs`,
+ `sdklib.impl`,
+ `sdklib.xml`,
+ })
}
func TestDefaults(t *testing.T) {
@@ -979,15 +1116,20 @@ func TestDroiddoc(t *testing.T) {
],
proofread_file: "libcore-proofread.txt",
todo_file: "libcore-docs-todo.html",
- args: "-offlinemode -title \"libcore\"",
+ flags: ["-offlinemode -title \"libcore\""],
}
`,
map[string][]byte{
"bar-doc/a.java": nil,
"bar-doc/b.java": nil,
})
+ barDocModule := ctx.ModuleForTests("bar-doc", "android_common")
+ barDoc := barDocModule.Rule("javadoc")
+ notExpected := " -stubs "
+ if strings.Contains(barDoc.RuleParams.Command, notExpected) {
+ t.Errorf("bar-doc command contains flag %q to create stubs, but should not", notExpected)
+ }
- barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc")
var javaSrcs []string
for _, i := range barDoc.Inputs {
javaSrcs = append(javaSrcs, i.Base())
@@ -996,7 +1138,7 @@ func TestDroiddoc(t *testing.T) {
t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
}
- aidl := ctx.ModuleForTests("bar-doc", "android_common").Rule("aidl")
+ aidl := barDocModule.Rule("aidl")
if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
}
@@ -1006,6 +1148,98 @@ func TestDroiddoc(t *testing.T) {
}
}
+func TestDroiddocArgsAndFlagsCausesError(t *testing.T) {
+ testJavaError(t, "flags is set. Cannot set args", `
+ droiddoc_exported_dir {
+ name: "droiddoc-templates-sdk",
+ path: ".",
+ }
+ filegroup {
+ name: "bar-doc-aidl-srcs",
+ srcs: ["bar-doc/IBar.aidl"],
+ path: "bar-doc",
+ }
+ droiddoc {
+ name: "bar-doc",
+ srcs: [
+ "bar-doc/a.java",
+ "bar-doc/IFoo.aidl",
+ ":bar-doc-aidl-srcs",
+ ],
+ exclude_srcs: [
+ "bar-doc/b.java"
+ ],
+ custom_template: "droiddoc-templates-sdk",
+ hdf: [
+ "android.whichdoc offline",
+ ],
+ knowntags: [
+ "bar-doc/known_oj_tags.txt",
+ ],
+ proofread_file: "libcore-proofread.txt",
+ todo_file: "libcore-docs-todo.html",
+ flags: ["-offlinemode -title \"libcore\""],
+ args: "-offlinemode -title \"libcore\"",
+ }
+ `)
+}
+
+func TestDroidstubs(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ droiddoc_exported_dir {
+ name: "droiddoc-templates-sdk",
+ path: ".",
+ }
+
+ droidstubs {
+ name: "bar-stubs",
+ srcs: [
+ "bar-doc/a.java",
+ ],
+ api_levels_annotations_dirs: [
+ "droiddoc-templates-sdk",
+ ],
+ api_levels_annotations_enabled: true,
+ }
+
+ droidstubs {
+ name: "bar-stubs-other",
+ srcs: [
+ "bar-doc/a.java",
+ ],
+ api_levels_annotations_dirs: [
+ "droiddoc-templates-sdk",
+ ],
+ api_levels_annotations_enabled: true,
+ api_levels_jar_filename: "android.other.jar",
+ }
+ `,
+ map[string][]byte{
+ "bar-doc/a.java": nil,
+ })
+ testcases := []struct {
+ moduleName string
+ expectedJarFilename string
+ }{
+ {
+ moduleName: "bar-stubs",
+ expectedJarFilename: "android.jar",
+ },
+ {
+ moduleName: "bar-stubs-other",
+ expectedJarFilename: "android.other.jar",
+ },
+ }
+ for _, c := range testcases {
+ m := ctx.ModuleForTests(c.moduleName, "android_common")
+ metalava := m.Rule("metalava")
+ expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+ if actual := metalava.RuleParams.Command; !strings.Contains(actual, expected) {
+ t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, actual)
+ }
+ }
+}
+
func TestDroidstubsWithSystemModules(t *testing.T) {
ctx, _ := testJava(t, `
droidstubs {
@@ -1276,8 +1510,7 @@ func TestJavaSdkLibrary(t *testing.T) {
// test if baz has exported SDK lib names foo and bar to qux
qux := ctx.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
- sdkLibs := quxLib.ExportedSdkLibs()
- sort.Strings(sdkLibs)
+ sdkLibs := android.SortedStringKeys(quxLib.ExportedSdkLibs())
if w := []string{"bar", "foo", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) {
t.Errorf("qux should export %q but exports %q", w, sdkLibs)
}
@@ -1345,6 +1578,28 @@ func TestJavaSdkLibrary_AccessOutputFiles_MissingScope(t *testing.T) {
`)
}
+func TestJavaSdkLibrary_Deps(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_sdk_library {
+ name: "sdklib",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ }
+ `)
+
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ `dex2oatd`,
+ `sdklib.impl`,
+ `sdklib.stubs`,
+ `sdklib.stubs.source`,
+ `sdklib.xml`,
+ })
+}
+
func TestJavaSdkLibraryImport_AccessOutputFiles(t *testing.T) {
testJava(t, `
java_sdk_library_import {
@@ -1808,3 +2063,52 @@ func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, m
t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
}
}
+
+func TestAidlExportIncludeDirsFromImports(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["aidl/foo/IFoo.aidl"],
+ libs: ["bar"],
+ }
+
+ java_import {
+ name: "bar",
+ jars: ["a.jar"],
+ aidl: {
+ export_include_dirs: ["aidl/bar"],
+ },
+ }
+ `)
+
+ aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ expectedAidlFlag := "-Iaidl/bar"
+ if !strings.Contains(aidlCommand, expectedAidlFlag) {
+ t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+ }
+}
+
+func TestDataNativeBinaries(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_test_host {
+ name: "foo",
+ srcs: ["a.java"],
+ data_native_bins: ["bin"]
+ }
+
+ python_binary_host {
+ name: "bin",
+ srcs: ["bin.py"],
+ }
+ `)
+
+ buildOS := android.BuildOs.String()
+
+ test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+ entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
+ expected := []string{buildDir + "/.intermediates/bin/" + buildOS + "_x86_64_PY3/bin:bin"}
+ actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
+ }
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index 4f636a59f..2b5ee7491 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -75,6 +75,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont
dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
+ dpInfo.Paths = android.FirstUniqueStrings(dpInfo.Paths)
moduleInfos[name] = dpInfo
mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/kotlin.go b/java/kotlin.go
index 673970b9c..e8c030aa7 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -31,7 +31,9 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
Command: `rm -rf "$classesDir" "$srcJarDir" "$kotlinBuildFile" "$emptyDir" && ` +
`mkdir -p "$classesDir" "$srcJarDir" "$emptyDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
- `${config.GenKotlinBuildFileCmd} $classpath "$name" $classesDir $out.rsp $srcJarDir/list > $kotlinBuildFile &&` +
+ `${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
+ ` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
+ ` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
`${config.KotlincCmd} ${config.JavacHeapFlags} $kotlincFlags ` +
`-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile -kotlin-home $emptyDir && ` +
`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
@@ -52,21 +54,43 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
Rspfile: "$out.rsp",
RspfileContent: `$in`,
},
- "kotlincFlags", "classpath", "srcJars", "srcJarDir", "classesDir", "kotlinJvmTarget", "kotlinBuildFile",
- "emptyDir", "name")
+ "kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir",
+ "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name")
+
+func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath {
+ if len(commonSrcFiles) > 0 {
+ // The list of common_srcs may be too long to put on the command line, but
+ // we can't use the rsp file because it is already being used for srcs.
+ // Insert a second rule to write out the list of resources to a file.
+ commonSrcsList := android.PathForModuleOut(ctx, "kotlinc_common_srcs.list")
+ rule := android.NewRuleBuilder()
+ rule.Command().Text("cp").FlagWithRspFileInputList("", commonSrcFiles).Output(commonSrcsList)
+ rule.Build(pctx, ctx, "kotlin_common_srcs_list", "kotlin common_srcs list")
+ return android.OptionalPathForPath(commonSrcsList)
+ }
+ return android.OptionalPath{}
+}
// kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile.
func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath,
- srcFiles, srcJars android.Paths,
+ srcFiles, commonSrcFiles, srcJars android.Paths,
flags javaBuilderFlags) {
var deps android.Paths
deps = append(deps, flags.kotlincClasspath...)
deps = append(deps, srcJars...)
+ deps = append(deps, commonSrcFiles...)
kotlinName := filepath.Join(ctx.ModuleDir(), ctx.ModuleSubDir(), ctx.ModuleName())
kotlinName = strings.ReplaceAll(kotlinName, "/", "__")
+ commonSrcsList := kotlinCommonSrcsList(ctx, commonSrcFiles)
+ commonSrcFilesArg := ""
+ if commonSrcsList.Valid() {
+ deps = append(deps, commonSrcsList.Path())
+ commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
+ }
+
ctx.Build(pctx, android.BuildParams{
Rule: kotlinc,
Description: "kotlinc",
@@ -74,13 +98,14 @@ func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath,
Inputs: srcFiles,
Implicits: deps,
Args: map[string]string{
- "classpath": flags.kotlincClasspath.FormJavaClassPath("-classpath"),
- "kotlincFlags": flags.kotlincFlags,
- "srcJars": strings.Join(srcJars.Strings(), " "),
- "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(),
- "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
- "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
- "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
+ "classpath": flags.kotlincClasspath.FormJavaClassPath(""),
+ "kotlincFlags": flags.kotlincFlags,
+ "commonSrcFilesArg": commonSrcFilesArg,
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "classesDir": android.PathForModuleOut(ctx, "kotlinc", "classes").String(),
+ "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
+ "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
+ "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
// http://b/69160377 kotlinc only supports -jvm-target 1.6 and 1.8
"kotlinJvmTarget": "1.8",
"name": kotlinName,
@@ -93,7 +118,9 @@ var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma:
Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` +
`mkdir -p "$srcJarDir" "$kaptDir/sources" "$kaptDir/classes" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
- `${config.GenKotlinBuildFileCmd} $classpath "$name" "" $out.rsp $srcJarDir/list > $kotlinBuildFile &&` +
+ `${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
+ ` --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
+ ` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
`${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} $kotlincFlags ` +
`-Xplugin=${config.KotlinKaptJar} ` +
`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
@@ -120,21 +147,31 @@ var kapt = pctx.AndroidRemoteStaticRule("kapt", android.RemoteRuleSupports{Goma:
RspfileContent: `$in`,
},
"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor",
- "classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile", "name",
- "classesJarOut")
+ "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir", "kotlinJvmTarget",
+ "kotlinBuildFile", "name", "classesJarOut")
// kotlinKapt performs Kotlin-compatible annotation processing. It takes .kt and .java sources and srcjars, and runs
// annotation processors over all of them, producing a srcjar of generated code in outputFile. The srcjar should be
// added as an additional input to kotlinc and javac rules, and the javac rule should have annotation processing
// disabled.
func kotlinKapt(ctx android.ModuleContext, srcJarOutputFile, resJarOutputFile android.WritablePath,
- srcFiles, srcJars android.Paths,
+ srcFiles, commonSrcFiles, srcJars android.Paths,
flags javaBuilderFlags) {
+ srcFiles = append(android.Paths(nil), srcFiles...)
+
var deps android.Paths
deps = append(deps, flags.kotlincClasspath...)
deps = append(deps, srcJars...)
deps = append(deps, flags.processorPath...)
+ deps = append(deps, commonSrcFiles...)
+
+ commonSrcsList := kotlinCommonSrcsList(ctx, commonSrcFiles)
+ commonSrcFilesArg := ""
+ if commonSrcsList.Valid() {
+ deps = append(deps, commonSrcsList.Path())
+ commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
+ }
kaptProcessorPath := flags.processorPath.FormRepeatedClassPath("-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=")
@@ -162,8 +199,9 @@ func kotlinKapt(ctx android.ModuleContext, srcJarOutputFile, resJarOutputFile an
Inputs: srcFiles,
Implicits: deps,
Args: map[string]string{
- "classpath": flags.kotlincClasspath.FormJavaClassPath("-classpath"),
+ "classpath": flags.kotlincClasspath.FormJavaClassPath(""),
"kotlincFlags": flags.kotlincFlags,
+ "commonSrcFilesArg": commonSrcFilesArg,
"srcJars": strings.Join(srcJars.Strings(), " "),
"srcJarDir": android.PathForModuleOut(ctx, "kapt", "srcJars").String(),
"kotlinBuildFile": android.PathForModuleOut(ctx, "kapt", "build.xml").String(),
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
new file mode 100644
index 000000000..021920af6
--- /dev/null
+++ b/java/legacy_core_platform_api_usage.go
@@ -0,0 +1,174 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+ "android/soong/java/config"
+)
+
+// This variable is effectively unused in pre-master branches, and is
+// included (with the same value as it has in AOSP) only to ease
+// merges between branches (see the comment in the
+// useLegacyCorePlatformApi() function):
+var legacyCorePlatformApiModules = []string{
+ "ahat-test-dump",
+ "android.car",
+ "android.test.mock",
+ "android.test.mock.impl",
+ "AoapTestDeviceApp",
+ "AoapTestHostApp",
+ "api-stubs-docs",
+ "art_cts_jvmti_test_library",
+ "art-gtest-jars-MyClassNatives",
+ "BackupFrameworksServicesRoboTests",
+ "BandwidthEnforcementTest",
+ "BlockedNumberProvider",
+ "BluetoothInstrumentationTests",
+ "BluetoothMidiService",
+ "car-apps-common",
+ "CertInstaller",
+ "ConnectivityManagerTest",
+ "ContactsProvider",
+ "core-tests-support",
+ "CtsContentTestCases",
+ "CtsIkeTestCases",
+ "CtsLibcoreWycheproofBCTestCases",
+ "CtsMediaTestCases",
+ "CtsNetTestCases",
+ "CtsNetTestCasesLatestSdk",
+ "CtsSecurityTestCases",
+ "CtsUsageStatsTestCases",
+ "DisplayCutoutEmulationEmu01Overlay",
+ "DocumentsUIPerfTests",
+ "DocumentsUITests",
+ "DownloadProvider",
+ "DownloadProviderTests",
+ "DownloadProviderUi",
+ "DynamicSystemInstallationService",
+ "EmergencyInfo-lib",
+ "ethernet-service",
+ "EthernetServiceTests",
+ "ExternalStorageProvider",
+ "ExtServices",
+ "ExtServices-core",
+ "framework-all",
+ "framework-minus-apex",
+ "FrameworksCoreTests",
+ "FrameworksIkeTests",
+ "FrameworksNetCommonTests",
+ "FrameworksNetTests",
+ "FrameworksServicesRoboTests",
+ "FrameworksServicesTests",
+ "FrameworksUtilTests",
+ "hid",
+ "hidl_test_java_java",
+ "hwbinder",
+ "ims",
+ "KeyChain",
+ "ksoap2",
+ "LocalTransport",
+ "lockagent",
+ "mediaframeworktest",
+ "MediaProvider",
+ "MmsService",
+ "MtpDocumentsProvider",
+ "MultiDisplayProvider",
+ "NetworkStackIntegrationTestsLib",
+ "NetworkStackNextIntegrationTests",
+ "NetworkStackNextTests",
+ "NetworkStackTests",
+ "NetworkStackTestsLib",
+ "NfcNci",
+ "platform_library-docs",
+ "PrintSpooler",
+ "RollbackTest",
+ "services",
+ "services.accessibility",
+ "services.backup",
+ "services.core.unboosted",
+ "services.devicepolicy",
+ "services.print",
+ "services.usage",
+ "services.usb",
+ "Settings-core",
+ "SettingsLib",
+ "SettingsProvider",
+ "SettingsProviderTest",
+ "SettingsRoboTests",
+ "Shell",
+ "ShellTests",
+ "sl4a.Common",
+ "StatementService",
+ "SystemUI-core",
+ "SystemUISharedLib",
+ "SystemUI-tests",
+ "Telecom",
+ "TelecomUnitTests",
+ "telephony-common",
+ "TelephonyProvider",
+ "TelephonyProviderTests",
+ "TeleService",
+ "testables",
+ "TetheringTests",
+ "TetheringTestsLib",
+ "time_zone_distro_installer",
+ "time_zone_distro_installer-tests",
+ "time_zone_distro-tests",
+ "time_zone_updater",
+ "TvProvider",
+ "uiautomator-stubs-docs",
+ "UsbHostExternalManagementTestApp",
+ "UserDictionaryProvider",
+ "WallpaperBackup",
+ "wifi-service",
+}
+
+// This variable is effectively unused in pre-master branches, and is
+// included (with the same value as it has in AOSP) only to ease
+// merges between branches (see the comment in the
+// useLegacyCorePlatformApi() function):
+var legacyCorePlatformApiLookup = make(map[string]struct{})
+
+func init() {
+ for _, module := range legacyCorePlatformApiModules {
+ legacyCorePlatformApiLookup[module] = struct{}{}
+ }
+}
+
+func useLegacyCorePlatformApi(ctx android.EarlyModuleContext) bool {
+ // In pre-master branches, we don't attempt to force usage of the stable
+ // version of the core/platform API. Instead, we always use the legacy
+ // version --- except in tests, where we always use stable, so that we
+ // can make the test assertions the same as other branches.
+ // This should be false in tests and true otherwise:
+ return ctx.Config().TestProductVariables == nil
+}
+
+func corePlatformSystemModules(ctx android.EarlyModuleContext) string {
+ if useLegacyCorePlatformApi(ctx) {
+ return config.LegacyCorePlatformSystemModules
+ } else {
+ return config.StableCorePlatformSystemModules
+ }
+}
+
+func corePlatformBootclasspathLibraries(ctx android.EarlyModuleContext) []string {
+ if useLegacyCorePlatformApi(ctx) {
+ return config.LegacyCorePlatformBootclasspathLibraries
+ } else {
+ return config.StableCorePlatformBootclasspathLibraries
+ }
+}
diff --git a/java/lint.go b/java/lint.go
index 20a7dc49f..3a210cc0b 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -17,6 +17,7 @@ package java
import (
"fmt"
"sort"
+ "strings"
"android/soong/android"
)
@@ -68,28 +69,78 @@ type linter struct {
outputs lintOutputs
properties LintProperties
+ reports android.Paths
+
buildModuleReportZip bool
}
type lintOutputs struct {
- html android.ModuleOutPath
- text android.ModuleOutPath
- xml android.ModuleOutPath
-
- transitiveHTML *android.DepSet
- transitiveText *android.DepSet
- transitiveXML *android.DepSet
+ html android.Path
+ text android.Path
+ xml android.Path
- transitiveHTMLZip android.OptionalPath
- transitiveTextZip android.OptionalPath
- transitiveXMLZip android.OptionalPath
+ depSets LintDepSets
}
-type lintOutputIntf interface {
+type lintOutputsIntf interface {
lintOutputs() *lintOutputs
}
-var _ lintOutputIntf = (*linter)(nil)
+type lintDepSetsIntf interface {
+ LintDepSets() LintDepSets
+}
+
+type LintDepSets struct {
+ HTML, Text, XML *android.DepSet
+}
+
+type LintDepSetsBuilder struct {
+ HTML, Text, XML *android.DepSetBuilder
+}
+
+func NewLintDepSetBuilder() LintDepSetsBuilder {
+ return LintDepSetsBuilder{
+ HTML: android.NewDepSetBuilder(android.POSTORDER),
+ Text: android.NewDepSetBuilder(android.POSTORDER),
+ XML: android.NewDepSetBuilder(android.POSTORDER),
+ }
+}
+
+func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
+ l.HTML.Direct(html)
+ l.Text.Direct(text)
+ l.XML.Direct(xml)
+ return l
+}
+
+func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
+ if depSets.HTML != nil {
+ l.HTML.Transitive(depSets.HTML)
+ }
+ if depSets.Text != nil {
+ l.Text.Transitive(depSets.Text)
+ }
+ if depSets.XML != nil {
+ l.XML.Transitive(depSets.XML)
+ }
+ return l
+}
+
+func (l LintDepSetsBuilder) Build() LintDepSets {
+ return LintDepSets{
+ HTML: l.HTML.Build(),
+ Text: l.Text.Build(),
+ XML: l.XML.Build(),
+ }
+}
+
+func (l *linter) LintDepSets() LintDepSets {
+ return l.outputs.depSets
+}
+
+var _ lintDepSetsIntf = (*linter)(nil)
+
+var _ lintOutputsIntf = (*linter)(nil)
func (l *linter) lintOutputs() *lintOutputs {
return &l.outputs
@@ -104,7 +155,16 @@ func (l *linter) deps(ctx android.BottomUpMutatorContext) {
return
}
- ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), extraLintCheckTag, l.properties.Lint.Extra_check_modules...)
+ extraCheckModules := l.properties.Lint.Extra_check_modules
+
+ if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
+ if checkOnlyModules := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); checkOnlyModules != "" {
+ extraCheckModules = strings.Split(checkOnlyModules, ",")
+ }
+ }
+
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
+ extraLintCheckTag, extraCheckModules...)
}
func (l *linter) writeLintProjectXML(ctx android.ModuleContext,
@@ -192,7 +252,7 @@ func (l *linter) writeLintProjectXML(ctx android.ModuleContext,
return projectXMLPath, configXMLPath, cacheDir, homeDir, deps
}
-// generateManifest adds a command to the rule to write a dummy manifest cat contains the
+// generateManifest adds a command to the rule to write a simple manifest that contains the
// minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest.
func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.Path {
manifestPath := android.PathForModuleOut(ctx, "lint", "AndroidManifest.xml")
@@ -237,16 +297,11 @@ func (l *linter) lint(ctx android.ModuleContext) {
text := android.PathForModuleOut(ctx, "lint-report.txt")
xml := android.PathForModuleOut(ctx, "lint-report.xml")
- htmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(html)
- textDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(text)
- xmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(xml)
+ depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
- if depLint, ok := dep.(lintOutputIntf); ok {
- depLintOutputs := depLint.lintOutputs()
- htmlDeps.Transitive(depLintOutputs.transitiveHTML)
- textDeps.Transitive(depLintOutputs.transitiveText)
- xmlDeps.Transitive(depLintOutputs.transitiveXML)
+ if depLint, ok := dep.(lintDepSetsIntf); ok {
+ depSetsBuilder.Transitive(depLint.LintDepSets())
}
})
@@ -254,7 +309,7 @@ func (l *linter) lint(ctx android.ModuleContext) {
rule.Command().Text("mkdir -p").Flag(cacheDir.String()).Flag(homeDir.String())
var annotationsZipPath, apiVersionsXMLPath android.Path
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
annotationsZipPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/annotations.zip")
apiVersionsXMLPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/api-versions.xml")
} else {
@@ -262,9 +317,9 @@ func (l *linter) lint(ctx android.ModuleContext) {
apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx)
}
- rule.Command().
+ cmd := rule.Command().
Text("(").
- Flag("JAVA_OPTS=-Xmx2048m").
+ Flag("JAVA_OPTS=-Xmx3072m").
FlagWithArg("ANDROID_SDK_HOME=", homeDir.String()).
FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath).
FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXMLPath).
@@ -282,9 +337,13 @@ func (l *linter) lint(ctx android.ModuleContext) {
FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())).
Flag("--exitcode").
Flags(l.properties.Lint.Flags).
- Implicits(deps).
- Text("|| (").Text("cat").Input(text).Text("; exit 7)").
- Text(")")
+ Implicits(deps)
+
+ if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
+ cmd.FlagWithArg("--check ", checkOnly)
+ }
+
+ cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
@@ -295,24 +354,33 @@ func (l *linter) lint(ctx android.ModuleContext) {
text: text,
xml: xml,
- transitiveHTML: htmlDeps.Build(),
- transitiveText: textDeps.Build(),
- transitiveXML: xmlDeps.Build(),
+ depSets: depSetsBuilder.Build(),
}
if l.buildModuleReportZip {
- htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
- l.outputs.transitiveHTMLZip = android.OptionalPathForPath(htmlZip)
- lintZip(ctx, l.outputs.transitiveHTML.ToSortedList(), htmlZip)
+ l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
+ }
+}
- textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
- l.outputs.transitiveTextZip = android.OptionalPathForPath(textZip)
- lintZip(ctx, l.outputs.transitiveText.ToSortedList(), textZip)
+func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
+ htmlList := depSets.HTML.ToSortedList()
+ textList := depSets.Text.ToSortedList()
+ xmlList := depSets.XML.ToSortedList()
- xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
- l.outputs.transitiveXMLZip = android.OptionalPathForPath(xmlZip)
- lintZip(ctx, l.outputs.transitiveXML.ToSortedList(), xmlZip)
+ if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
+ return nil
}
+
+ htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
+ lintZip(ctx, htmlList, htmlZip)
+
+ textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
+ lintZip(ctx, textList, textZip)
+
+ xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
+ lintZip(ctx, xmlList, xmlZip)
+
+ return android.Paths{htmlZip, textZip, xmlZip}
}
type lintSingleton struct {
@@ -327,7 +395,7 @@ func (l *lintSingleton) GenerateBuildActions(ctx android.SingletonContext) {
}
func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) {
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return
}
@@ -389,7 +457,7 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
return
}
- if l, ok := m.(lintOutputIntf); ok {
+ if l, ok := m.(lintOutputsIntf); ok {
outputs = append(outputs, l.lintOutputs())
}
})
@@ -400,7 +468,9 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
var paths android.Paths
for _, output := range outputs {
- paths = append(paths, get(output))
+ if p := get(output); p != nil {
+ paths = append(paths, p)
+ }
}
lintZip(ctx, paths, outputPath)
@@ -443,7 +513,7 @@ func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android
rule.Command().BuiltTool(ctx, "soong_zip").
FlagWithOutput("-o ", outputPath).
FlagWithArg("-C ", android.PathForIntermediates(ctx).String()).
- FlagWithRspFileInputList("-l ", paths)
+ FlagWithRspFileInputList("-r ", paths)
rule.Build(pctx, ctx, outputPath.Base(), outputPath.Base())
}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 999c72f3c..ac8337dc5 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -34,6 +34,10 @@ func RegisterPrebuiltApisBuildComponents(ctx android.RegistrationContext) {
type prebuiltApisProperties struct {
// list of api version directories
Api_dirs []string
+
+ // The sdk_version of java_import modules generated based on jar files.
+ // Defaults to "current"
+ Imports_sdk_version *string
}
type prebuiltApis struct {
@@ -74,7 +78,7 @@ func prebuiltApiModuleName(mctx android.LoadHookContext, module string, scope st
return mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module
}
-func createImport(mctx android.LoadHookContext, module string, scope string, apiver string, path string) {
+func createImport(mctx android.LoadHookContext, module, scope, apiver, path, sdk_version string) {
props := struct {
Name *string
Jars []string
@@ -83,8 +87,7 @@ func createImport(mctx android.LoadHookContext, module string, scope string, api
}{}
props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, apiver))
props.Jars = append(props.Jars, path)
- // TODO(hansson): change to scope after migration is done.
- props.Sdk_version = proptools.StringPtr("current")
+ props.Sdk_version = proptools.StringPtr(sdk_version)
props.Installable = proptools.BoolPtr(false)
mctx.CreateModule(ImportFactory, &props)
@@ -101,10 +104,10 @@ func createFilegroup(mctx android.LoadHookContext, module string, scope string,
mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
}
-func getPrebuiltFiles(mctx android.LoadHookContext, name string) []string {
+func getPrebuiltFiles(mctx android.LoadHookContext, p *prebuiltApis, name string) []string {
mydir := mctx.ModuleDir() + "/"
var files []string
- for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs {
+ for _, apiver := range p.properties.Api_dirs {
for _, scope := range []string{"public", "system", "test", "core", "module-lib", "system-server"} {
vfiles, err := mctx.GlobWithDeps(mydir+apiver+"/"+scope+"/"+name, nil)
if err != nil {
@@ -116,16 +119,18 @@ func getPrebuiltFiles(mctx android.LoadHookContext, name string) []string {
return files
}
-func prebuiltSdkStubs(mctx android.LoadHookContext) {
+func prebuiltSdkStubs(mctx android.LoadHookContext, p *prebuiltApis) {
mydir := mctx.ModuleDir() + "/"
// <apiver>/<scope>/<module>.jar
- files := getPrebuiltFiles(mctx, "*.jar")
+ files := getPrebuiltFiles(mctx, p, "*.jar")
+
+ sdk_version := proptools.StringDefault(p.properties.Imports_sdk_version, "current")
for _, f := range files {
// create a Import module for each jar file
localPath := strings.TrimPrefix(f, mydir)
module, apiver, scope := parseJarPath(localPath)
- createImport(mctx, module, scope, apiver, localPath)
+ createImport(mctx, module, scope, apiver, localPath, sdk_version)
}
}
@@ -140,8 +145,8 @@ func createSystemModules(mctx android.LoadHookContext, apiver string) {
mctx.CreateModule(SystemModulesFactory, &props)
}
-func prebuiltSdkSystemModules(mctx android.LoadHookContext) {
- for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs {
+func prebuiltSdkSystemModules(mctx android.LoadHookContext, p *prebuiltApis) {
+ for _, apiver := range p.properties.Api_dirs {
jar := android.ExistentPathForSource(mctx,
mctx.ModuleDir(), apiver, "public", "core-for-system-modules.jar")
if jar.Valid() {
@@ -150,10 +155,10 @@ func prebuiltSdkSystemModules(mctx android.LoadHookContext) {
}
}
-func prebuiltApiFiles(mctx android.LoadHookContext) {
+func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
mydir := mctx.ModuleDir() + "/"
// <apiver>/<scope>/api/<module>.txt
- files := getPrebuiltFiles(mctx, "api/*.txt")
+ files := getPrebuiltFiles(mctx, p, "api/*.txt")
if len(files) == 0 {
mctx.ModuleErrorf("no api file found under %q", mydir)
@@ -201,10 +206,10 @@ func prebuiltApiFiles(mctx android.LoadHookContext) {
}
func createPrebuiltApiModules(mctx android.LoadHookContext) {
- if _, ok := mctx.Module().(*prebuiltApis); ok {
- prebuiltApiFiles(mctx)
- prebuiltSdkStubs(mctx)
- prebuiltSdkSystemModules(mctx)
+ if p, ok := mctx.Module().(*prebuiltApis); ok {
+ prebuiltApiFiles(mctx, p)
+ prebuiltSdkStubs(mctx, p)
+ prebuiltSdkSystemModules(mctx, p)
}
}
diff --git a/java/robolectric.go b/java/robolectric.go
index c6b07a17e..3fe6626bb 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -21,10 +21,13 @@ import (
"strings"
"android/soong/android"
+ "android/soong/java/config"
+ "android/soong/tradefed"
)
func init() {
android.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
+ android.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
}
var robolectricDefaultLibs = []string{
@@ -32,10 +35,13 @@ var robolectricDefaultLibs = []string{
"Robolectric_all-target",
"mockito-robolectric-prebuilt",
"truth-prebuilt",
+ // TODO(ccross): this is not needed at link time
+ "junitxml",
}
var (
- roboCoverageLibsTag = dependencyTag{name: "roboSrcs"}
+ roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
+ roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
)
type robolectricProperties struct {
@@ -58,13 +64,28 @@ type robolectricTest struct {
Library
robolectricProperties robolectricProperties
+ testProperties testProperties
libs []string
tests []string
+ manifest android.Path
+ resourceApk android.Path
+
+ combinedJar android.WritablePath
+
roboSrcJar android.Path
+
+ testConfig android.Path
+ data android.Paths
+}
+
+func (r *robolectricTest) TestSuites() []string {
+ return r.testProperties.Test_suites
}
+var _ android.TestSuiteModule = (*robolectricTest)(nil)
+
func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
r.Library.DepsMutator(ctx)
@@ -77,9 +98,16 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
+
+ ctx.AddVariationDependencies(nil, roboRuntimesTag, "robolectric-android-all-prebuilts")
}
func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
+ r.testProperties.Test_config_template, r.testProperties.Test_suites,
+ r.testProperties.Auto_gen_config)
+ r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
+
roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
Join(ctx, "com/android/tools/test_config.properties")
@@ -95,6 +123,9 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
}
+ r.manifest = instrumentedApp.mergedManifestFile
+ r.resourceApk = instrumentedApp.outputFile
+
generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp)
r.extraResources = android.Paths{roboTestConfig}
@@ -104,10 +135,30 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp)
r.roboSrcJar = roboSrcJar
+ roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
+ generateSameDirRoboTestConfigJar(ctx, roboTestConfigJar)
+
+ combinedJarJars := android.Paths{
+ // roboTestConfigJar comes first so that its com/android/tools/test_config.properties
+ // overrides the one from r.extraResources. The r.extraResources one can be removed
+ // once the Make test runner is removed.
+ roboTestConfigJar,
+ r.outputFile,
+ instrumentedApp.implementationAndResourcesJar,
+ }
+
for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
- r.libs = append(r.libs, dep.(Dependency).BaseModuleName())
+ m := dep.(Dependency)
+ r.libs = append(r.libs, m.BaseModuleName())
+ if !android.InList(m.BaseModuleName(), config.FrameworkLibraries) {
+ combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars()...)
+ }
}
+ r.combinedJar = android.PathForModuleOut(ctx, "robolectric_combined", r.outputFile.Base())
+ TransformJarsToJar(ctx, r.combinedJar, "combine jars", combinedJarJars, android.OptionalPath{},
+ false, nil, nil)
+
// TODO: this could all be removed if tradefed was used as the test runner, it will find everything
// annotated as a test and run it.
for _, src := range r.compiledJavaSrcs {
@@ -121,14 +172,38 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
}
r.tests = append(r.tests, s)
}
+
+ r.data = append(r.data, r.manifest, r.resourceApk)
+
+ runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
+
+ installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
+
+ installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk)
+ installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest)
+ installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
+
+ var installDeps android.Paths
+ for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
+ installDeps = append(installDeps, runtime)
+ }
+ installDeps = append(installDeps, installedResourceApk, installedManifest, installedConfig)
+
+ for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) {
+ installedData := ctx.InstallFile(installPath, data.Rel(), data)
+ installDeps = append(installDeps, installedData)
+ }
+
+ ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
}
-func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath, instrumentedApp *AndroidApp) {
+func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
+ instrumentedApp *AndroidApp) {
+ rule := android.NewRuleBuilder()
+
manifest := instrumentedApp.mergedManifestFile
resourceApk := instrumentedApp.outputFile
- rule := android.NewRuleBuilder()
-
rule.Command().Text("rm -f").Output(outputFile)
rule.Command().
Textf(`echo "android_merged_manifest=%s" >>`, manifest.String()).Output(outputFile).Text("&&").
@@ -141,6 +216,28 @@ func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.Writab
rule.Build(pctx, ctx, "generate_test_config", "generate test_config.properties")
}
+func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
+ rule := android.NewRuleBuilder()
+
+ outputDir := outputFile.InSameDir(ctx)
+ configFile := outputDir.Join(ctx, "com/android/tools/test_config.properties")
+ rule.Temporary(configFile)
+ rule.Command().Text("rm -f").Output(outputFile).Output(configFile)
+ rule.Command().Textf("mkdir -p $(dirname %s)", configFile.String())
+ rule.Command().
+ Text("(").
+ Textf(`echo "android_merged_manifest=%s-AndroidManifest.xml" &&`, ctx.ModuleName()).
+ Textf(`echo "android_resource_apk=%s.apk"`, ctx.ModuleName()).
+ Text(") >>").Output(configFile)
+ rule.Command().
+ BuiltTool(ctx, "soong_zip").
+ FlagWithArg("-C ", outputDir.String()).
+ FlagWithInput("-f ", configFile).
+ FlagWithOutput("-o ", outputFile)
+
+ rule.Build(pctx, ctx, "generate_test_config_samedir", "generate test_config.properties")
+}
+
func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath,
instrumentedApp *AndroidApp) {
@@ -202,7 +299,6 @@ func (r *robolectricTest) writeTestRunner(w io.Writer, module, name string, test
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
}
fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
-
}
// An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
@@ -218,11 +314,82 @@ func RobolectricTestFactory() android.Module {
module.addHostProperties()
module.AddProperties(
&module.Module.deviceProperties,
- &module.robolectricProperties)
+ &module.robolectricProperties,
+ &module.testProperties)
module.Module.dexpreopter.isTest = true
module.Module.linter.test = true
+ module.testProperties.Test_suites = []string{"robolectric-tests"}
+
InitJavaModule(module, android.DeviceSupported)
return module
}
+
+func (r *robolectricTest) InstallBypassMake() bool { return true }
+func (r *robolectricTest) InstallInTestcases() bool { return true }
+func (r *robolectricTest) InstallForceOS() *android.OsType { return &android.BuildOs }
+
+func robolectricRuntimesFactory() android.Module {
+ module := &robolectricRuntimes{}
+ module.AddProperties(&module.props)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+type robolectricRuntimesProperties struct {
+ Jars []string `android:"path"`
+ Lib *string
+}
+
+type robolectricRuntimes struct {
+ android.ModuleBase
+
+ props robolectricRuntimesProperties
+
+ runtimes []android.InstallPath
+}
+
+func (r *robolectricRuntimes) TestSuites() []string {
+ return []string{"robolectric-tests"}
+}
+
+var _ android.TestSuiteModule = (*robolectricRuntimes)(nil)
+
+func (r *robolectricRuntimes) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
+ ctx.AddVariationDependencies(nil, libTag, String(r.props.Lib))
+ }
+}
+
+func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ files := android.PathsForModuleSrc(ctx, r.props.Jars)
+
+ androidAllDir := android.PathForModuleInstall(ctx, "android-all")
+ for _, from := range files {
+ installedRuntime := ctx.InstallFile(androidAllDir, from.Base(), from)
+ r.runtimes = append(r.runtimes, installedRuntime)
+ }
+
+ if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
+ runtimeFromSourceModule := ctx.GetDirectDepWithTag(String(r.props.Lib), libTag)
+ if runtimeFromSourceModule == nil {
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{String(r.props.Lib)})
+ } else {
+ ctx.PropertyErrorf("lib", "missing dependency %q", String(r.props.Lib))
+ }
+ return
+ }
+ runtimeFromSourceJar := android.OutputFileForModule(ctx, runtimeFromSourceModule, "")
+
+ runtimeName := fmt.Sprintf("android-all-%s-robolectric-r0.jar",
+ ctx.Config().PlatformSdkCodename())
+ installedRuntime := ctx.InstallFile(androidAllDir, runtimeName, runtimeFromSourceJar)
+ r.runtimes = append(r.runtimes, installedRuntime)
+ }
+}
+
+func (r *robolectricRuntimes) InstallBypassMake() bool { return true }
+func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
+func (r *robolectricRuntimes) InstallForceOS() *android.OsType { return &android.BuildOs }
diff --git a/java/sdk.go b/java/sdk.go
index f96ecded4..56fa12b3e 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -53,7 +53,7 @@ type sdkContext interface {
func UseApiFingerprint(ctx android.BaseModuleContext) bool {
if ctx.Config().UnbundledBuild() &&
- !ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+ !ctx.Config().AlwaysUsePrebuiltSdks() &&
ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
return true
}
@@ -94,9 +94,9 @@ func (k sdkKind) String() string {
case sdkCorePlatform:
return "core_platform"
case sdkModule:
- return "module"
+ return "module-lib"
case sdkSystemServer:
- return "system_server"
+ return "system-server"
default:
return "invalid"
}
@@ -191,19 +191,22 @@ func (s sdkSpec) prebuiltSdkAvailableForUnbundledBuild() bool {
return s.kind != sdkPrivate && s.kind != sdkNone && s.kind != sdkCorePlatform
}
-// forPdkBuild converts this sdkSpec into another sdkSpec that is for the PDK builds.
-func (s sdkSpec) forPdkBuild(ctx android.EarlyModuleContext) sdkSpec {
- // For PDK builds, use the latest SDK version instead of "current" or ""
- if s.kind == sdkPrivate || s.kind == sdkPublic {
- kind := s.kind
- if kind == sdkPrivate {
- // We don't have prebuilt SDK for private APIs, so use the public SDK
- // instead. This looks odd, but that's how it has been done.
- // TODO(b/148271073): investigate the need for this.
- kind = sdkPublic
+func (s sdkSpec) forVendorPartition(ctx android.EarlyModuleContext) sdkSpec {
+ // If BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES has a numeric value,
+ // use it instead of "current" for the vendor partition.
+ currentSdkVersion := ctx.DeviceConfig().CurrentApiLevelForVendorModules()
+ if currentSdkVersion == "current" {
+ return s
+ }
+
+ if s.kind == sdkPublic || s.kind == sdkSystem {
+ if s.version.isCurrent() {
+ if i, err := strconv.Atoi(currentSdkVersion); err == nil {
+ version := sdkVersion(i)
+ return sdkSpec{s.kind, version, s.raw}
+ }
+ panic(fmt.Errorf("BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES must be either \"current\" or a number, but was %q", currentSdkVersion))
}
- version := sdkVersion(LatestSdkVersionInt(ctx))
- return sdkSpec{kind, version, s.raw}
}
return s
}
@@ -212,9 +215,9 @@ func (s sdkSpec) forPdkBuild(ctx android.EarlyModuleContext) sdkSpec {
func (s sdkSpec) usePrebuilt(ctx android.EarlyModuleContext) bool {
if s.version.isCurrent() {
// "current" can be built from source and be from prebuilt SDK
- return ctx.Config().UnbundledBuildUsePrebuiltSdks()
+ return ctx.Config().AlwaysUsePrebuiltSdks()
} else if s.version.isNumbered() {
- // sanity check
+ // validation check
if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
return false
@@ -233,8 +236,9 @@ func (s sdkSpec) effectiveVersion(ctx android.EarlyModuleContext) (sdkVersion, e
if !s.valid() {
return s.version, fmt.Errorf("invalid sdk version %q", s.raw)
}
- if ctx.Config().IsPdkBuild() {
- s = s.forPdkBuild(ctx)
+
+ if ctx.DeviceSpecific() || ctx.SocSpecific() {
+ s = s.forVendorPartition(ctx)
}
if s.version.isNumbered() {
return s.version, nil
@@ -321,6 +325,28 @@ func sdkSpecFrom(str string) sdkSpec {
}
}
+func (s sdkSpec) validateSystemSdk(ctx android.EarlyModuleContext) bool {
+ // Ensures that the specified system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor/product Java module)
+ // Assuming that BOARD_SYSTEMSDK_VERSIONS := 28 29,
+ // sdk_version of the modules in vendor/product that use system sdk must be either system_28, system_29 or system_current
+ if s.kind != sdkSystem || !s.version.isNumbered() {
+ return true
+ }
+ allowedVersions := ctx.DeviceConfig().PlatformSystemSdkVersions()
+ if ctx.DeviceSpecific() || ctx.SocSpecific() || (ctx.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
+ systemSdkVersions := ctx.DeviceConfig().SystemSdkVersions()
+ if len(systemSdkVersions) > 0 {
+ allowedVersions = systemSdkVersions
+ }
+ }
+ if len(allowedVersions) > 0 && !android.InList(s.version.String(), allowedVersions) {
+ ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
+ s.raw, allowedVersions)
+ return false
+ }
+ return true
+}
+
func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep {
sdkVersion := sdkContext.sdkVersion()
if !sdkVersion.valid() {
@@ -328,8 +354,12 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
return sdkDep{}
}
- if ctx.Config().IsPdkBuild() {
- sdkVersion = sdkVersion.forPdkBuild(ctx)
+ if ctx.DeviceSpecific() || ctx.SocSpecific() {
+ sdkVersion = sdkVersion.forVendorPartition(ctx)
+ }
+
+ if !sdkVersion.validateSystemSdk(ctx) {
+ return sdkDep{}
}
if sdkVersion.usePrebuilt(ctx) {
@@ -384,25 +414,13 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
}
}
- // Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks)
- // or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set)
- if sdkVersion.kind == sdkSystem && sdkVersion.version.isNumbered() {
- allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions()
- if ctx.DeviceSpecific() || ctx.SocSpecific() {
- if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 {
- allowed_versions = ctx.DeviceConfig().SystemSdkVersions()
- }
- }
- if len(allowed_versions) > 0 && !android.InList(sdkVersion.version.String(), allowed_versions) {
- ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
- sdkVersion.raw, allowed_versions)
- }
- }
-
switch sdkVersion.kind {
case sdkPrivate:
return sdkDep{
- useDefaultLibs: true,
+ useModule: true,
+ systemModules: corePlatformSystemModules(ctx),
+ bootclasspath: corePlatformBootclasspathLibraries(ctx),
+ classpath: config.FrameworkLibraries,
frameworkResModule: "framework-res",
}
case sdkNone:
@@ -424,9 +442,10 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
}
case sdkCorePlatform:
return sdkDep{
- useDefaultLibs: true,
- frameworkResModule: "framework-res",
- noFrameworksLibs: true,
+ useModule: true,
+ systemModules: corePlatformSystemModules(ctx),
+ bootclasspath: corePlatformBootclasspathLibraries(ctx),
+ noFrameworksLibs: true,
}
case sdkPublic:
return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
@@ -435,7 +454,12 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep
case sdkTest:
return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
case sdkCore:
- return toModule([]string{"core.current.stubs"}, "", nil)
+ return sdkDep{
+ useModule: true,
+ bootclasspath: []string{"core.current.stubs", config.DefaultLambdaStubsLibrary},
+ systemModules: "core-current-stubs-system-modules",
+ noFrameworksLibs: true,
+ }
case sdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", nonUpdatableFrameworkAidlPath(ctx))
@@ -492,7 +516,7 @@ func sdkSingletonFactory() android.Singleton {
type sdkSingleton struct{}
func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return
}
@@ -612,10 +636,7 @@ func createAPIFingerprint(ctx android.SingletonContext) {
if ctx.Config().PlatformSdkCodename() == "REL" {
cmd.Text("echo REL >").Output(out)
- } else if ctx.Config().IsPdkBuild() {
- // TODO: get this from the PDK artifacts?
- cmd.Text("echo PDK >").Output(out)
- } else if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ } else if !ctx.Config().AlwaysUsePrebuiltSdks() {
in, err := ctx.GlobWithDeps("frameworks/base/api/*current.txt", nil)
if err != nil {
ctx.Errorf("error globbing API files: %s", err)
@@ -644,7 +665,7 @@ func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
}
func sdkMakeVars(ctx android.MakeVarsContext) {
- if ctx.Config().UnbundledBuildUsePrebuiltSdks() || ctx.Config().IsPdkBuild() {
+ if ctx.Config().AlwaysUsePrebuiltSdks() {
return
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 679c07597..88cf46826 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -70,6 +70,12 @@ func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep andr
}
}
+var _ android.ReplaceSourceWithPrebuilt = (*scopeDependencyTag)(nil)
+
+func (tag scopeDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
+}
+
// Provides information about an api scope, e.g. public, system, test.
type apiScope struct {
// The name of the api scope, e.g. public, system, test
@@ -120,24 +126,23 @@ type apiScope struct {
// the prebuilt jar.
sdkVersion string
- // Extra arguments to pass to droidstubs for this scope.
- droidstubsArgs []string
+ // The annotation that identifies this API level, empty for the public API scope.
+ annotation string
- // The args that must be passed to droidstubs to generate the stubs source
- // for this scope.
+ // Extra arguments to pass to droidstubs for this scope.
//
- // The stubs source must include the definitions of everything that is in this
- // api scope and all the scopes that this one extends.
- droidstubsArgsForGeneratingStubsSource []string
+ // This is not used directly but is used to construct the droidstubsArgs.
+ extraArgs []string
- // The args that must be passed to droidstubs to generate the API for this scope.
+ // The args that must be passed to droidstubs to generate the API and stubs source
+ // for this scope, constructed dynamically by initApiScope().
//
// The API only includes the additional members that this scope adds over the scope
// that it extends.
- droidstubsArgsForGeneratingApi []string
-
- // True if the stubs source and api can be created by the same metalava invocation.
- createStubsSourceAndApiTogether bool
+ //
+ // The stubs source must include the definitions of everything that is in this
+ // api scope and all the scopes that this one extends.
+ droidstubsArgs []string
// Whether the api scope can be treated as unstable, and should skip compat checks.
unstable bool
@@ -174,21 +179,23 @@ func initApiScope(scope *apiScope) *apiScope {
// To get the args needed to generate the stubs source append all the args from
// this scope and all the scopes it extends as each set of args adds additional
// members to the stubs.
- var stubsSourceArgs []string
- for s := scope; s != nil; s = s.extends {
- stubsSourceArgs = append(stubsSourceArgs, s.droidstubsArgs...)
+ var scopeSpecificArgs []string
+ if scope.annotation != "" {
+ scopeSpecificArgs = []string{"--show-annotation", scope.annotation}
}
- scope.droidstubsArgsForGeneratingStubsSource = stubsSourceArgs
+ for s := scope; s != nil; s = s.extends {
+ scopeSpecificArgs = append(scopeSpecificArgs, s.extraArgs...)
- // Currently the args needed to generate the API are the same as the args
- // needed to add additional members.
- apiArgs := scope.droidstubsArgs
- scope.droidstubsArgsForGeneratingApi = apiArgs
+ // Ensure that the generated stubs includes all the API elements from the API scope
+ // that this scope extends.
+ if s != scope && s.annotation != "" {
+ scopeSpecificArgs = append(scopeSpecificArgs, "--show-for-stub-purposes-annotation", s.annotation)
+ }
+ }
- // If the args needed to generate the stubs and API are the same then they
- // can be generated in a single invocation of metalava, otherwise they will
- // need separate invocations.
- scope.createStubsSourceAndApiTogether = reflect.DeepEqual(stubsSourceArgs, apiArgs)
+ // Escape any special characters in the arguments. This is needed because droidstubs
+ // passes these directly to the shell command.
+ scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
return scope
}
@@ -243,10 +250,10 @@ var (
scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
return &module.sdkLibraryProperties.System
},
- apiFilePrefix: "system-",
- moduleSuffix: ".system",
- sdkVersion: "system_current",
- droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"},
+ apiFilePrefix: "system-",
+ moduleSuffix: ".system",
+ sdkVersion: "system_current",
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)",
})
apiScopeTest = initApiScope(&apiScope{
name: "test",
@@ -255,11 +262,11 @@ var (
scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
return &module.sdkLibraryProperties.Test
},
- apiFilePrefix: "test-",
- moduleSuffix: ".test",
- sdkVersion: "test_current",
- droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
- unstable: true,
+ apiFilePrefix: "test-",
+ moduleSuffix: ".test",
+ sdkVersion: "test_current",
+ annotation: "android.annotation.TestApi",
+ unstable: true,
})
apiScopeModuleLib = initApiScope(&apiScope{
name: "module-lib",
@@ -276,9 +283,7 @@ var (
apiFilePrefix: "module-lib-",
moduleSuffix: ".module_lib",
sdkVersion: "module_current",
- droidstubsArgs: []string{
- "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
- },
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)",
})
apiScopeSystemServer = initApiScope(&apiScope{
name: "system-server",
@@ -295,11 +300,11 @@ var (
apiFilePrefix: "system-server-",
moduleSuffix: ".system_server",
sdkVersion: "system_server_current",
- droidstubsArgs: []string{
- "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\) ",
- "--hide-annotation android.annotation.Hide",
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.SYSTEM_SERVER)",
+ extraArgs: []string{
+ "--hide-annotation", "android.annotation.Hide",
// com.android.* classes are okay in this interface"
- "--hide InternalClasses",
+ "--hide", "InternalClasses",
},
})
allApiScopes = apiScopes{
@@ -847,22 +852,20 @@ func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(moduleBase *andr
}
// to satisfy SdkLibraryComponentDependency
-func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() []string {
- if e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack != nil {
- return []string{*e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack}
- }
- return nil
+func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() *string {
+ return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
}
// 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
+
// The optional name of the sdk library that should be implicitly added to the
// AndroidManifest of an app that contains code which references the sdk library.
//
- // Returns an array containing 0 or 1 items rather than a *string to make it easier
- // to append this to the list of exported sdk libraries.
- OptionalImplicitSdkLibrary() []string
+ // Returns the name of the optional implicit SDK library or nil, if there isn't one.
+ OptionalImplicitSdkLibrary() *string
}
// Make sure that all the module types that are components of java_sdk_library/_import
@@ -976,21 +979,14 @@ func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}
-func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+// Add the dependencies on the child modules in the component deps mutator.
+func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
for _, apiScope := range module.getGeneratedApiScopes(ctx) {
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
- // If the stubs source and API cannot be generated together then add an additional dependency on
- // the API module.
- if apiScope.createStubsSourceAndApiTogether {
- // Add a dependency on the stubs source in order to access both stubs source and api information.
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
- } else {
- // Add separate dependencies on the creators of the stubs source files and the API.
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
- ctx.AddVariationDependencies(nil, apiScope.apiFileTag, module.apiModuleName(apiScope))
- }
+ // Add a dependency on the stubs source in order to access both stubs source and api information.
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
}
if module.requiresRuntimeImplementationLibrary() {
@@ -1001,7 +997,12 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependency to the rule for generating the xml permissions file
ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName())
}
+ }
+}
+// Add other dependencies as normal.
+func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if module.requiresRuntimeImplementationLibrary() {
// Only add the deps for the library if it is actually going to be built.
module.Library.deps(ctx)
}
@@ -1045,8 +1046,10 @@ func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
return nil
}
entriesList := module.Library.AndroidMkEntries()
- entries := &entriesList[0]
- entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
+ if module.sharedLibrary() {
+ entries := &entriesList[0]
+ entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
+ }
return entriesList
}
@@ -1086,11 +1089,25 @@ func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) stri
return ":" + module.BaseModuleName() + "-removed.api." + apiScope.name + ".latest"
}
+func childModuleVisibility(childVisibility []string) []string {
+ if childVisibility == nil {
+ // No child visibility set. The child will use the visibility of the sdk_library.
+ return nil
+ }
+
+ // Prepend an override to ignore the sdk_library's visibility, and rely on the child visibility.
+ var visibility []string
+ visibility = append(visibility, "//visibility:override")
+ visibility = append(visibility, childVisibility...)
+ return visibility
+}
+
// Creates the implementation java library
func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
-
moduleNamePtr := proptools.StringPtr(module.BaseModuleName())
+ visibility := childModuleVisibility(module.sdkLibraryProperties.Impl_library_visibility)
+
props := struct {
Name *string
Visibility []string
@@ -1098,7 +1115,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
ConfigurationName *string
}{
Name: proptools.StringPtr(module.implLibraryModuleName()),
- Visibility: module.sdkLibraryProperties.Impl_library_visibility,
+ Visibility: visibility,
// Set the instrument property to ensure it is instrumented when instrumentation is required.
Instrument: true,
@@ -1110,6 +1127,7 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
&module.properties,
&module.protoProperties,
&module.deviceProperties,
+ &module.dexProperties,
&module.dexpreoptProperties,
&module.linter.properties,
&props,
@@ -1121,22 +1139,17 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
// Creates a static java library that has API stubs
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
props := struct {
- Name *string
- Visibility []string
- Srcs []string
- Installable *bool
- Sdk_version *string
- System_modules *string
- Patch_module *string
- Libs []string
- Compile_dex *bool
- Java_version *string
- Product_variables struct {
- Pdk struct {
- Enabled *bool
- }
- }
- Openjdk9 struct {
+ Name *string
+ Visibility []string
+ Srcs []string
+ Installable *bool
+ Sdk_version *string
+ System_modules *string
+ Patch_module *string
+ Libs []string
+ Compile_dex *bool
+ Java_version *string
+ Openjdk9 struct {
Srcs []string
Javacflags []string
}
@@ -1149,12 +1162,7 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
}{}
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
-
- // If stubs_library_visibility is not set then the created module will use the
- // visibility of this module.
- visibility := module.sdkLibraryProperties.Stubs_library_visibility
- props.Visibility = visibility
-
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
// sources are generated from the droiddoc
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
@@ -1168,14 +1176,13 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
if proptools.Bool(module.sdkLibraryProperties.Annotations_enabled) {
props.Libs = append(props.Libs, "stub-annotations")
}
- props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
- if module.deviceProperties.Compile_dex != nil {
- props.Compile_dex = module.deviceProperties.Compile_dex
+ if module.dexProperties.Compile_dex != nil {
+ props.Compile_dex = module.dexProperties.Compile_dex
}
// Dist the class jar artifact for sdk builds.
@@ -1191,7 +1198,7 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
// Creates a droidstubs module that creates stubs source files from the given full source
// files and also updates and checks the API specification files.
-func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, createStubSources, createApi bool, scopeSpecificDroidstubsArgs []string) {
+func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
props := struct {
Name *string
Visibility []string
@@ -1236,12 +1243,7 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
// * libs (static_libs/libs)
props.Name = proptools.StringPtr(name)
-
- // If stubs_source_visibility is not set then the created module will use the
- // visibility of this module.
- visibility := module.sdkLibraryProperties.Stubs_source_visibility
- props.Visibility = visibility
-
+ props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_source_visibility)
props.Srcs = append(props.Srcs, module.properties.Srcs...)
props.Sdk_version = module.deviceProperties.Sdk_version
props.System_modules = module.deviceProperties.System_modules
@@ -1280,64 +1282,57 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC
}
droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
- if !createStubSources {
- // Stubs are not required.
- props.Generate_stubs = proptools.BoolPtr(false)
- }
-
// Add in scope specific arguments.
droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
- if createApi {
- // List of APIs identified from the provided source files are created. They are later
- // compared against to the not-yet-released (a.k.a current) list of APIs and to the
- // last-released (a.k.a numbered) list of API.
- currentApiFileName := apiScope.apiFilePrefix + "current.txt"
- removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
- apiDir := module.getApiDir()
- currentApiFileName = path.Join(apiDir, currentApiFileName)
- removedApiFileName = path.Join(apiDir, removedApiFileName)
-
- // check against the not-yet-release API
- props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
- props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
-
- if !apiScope.unstable {
- // check against the latest released API
- latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
- props.Check_api.Last_released.Api_file = latestApiFilegroupName
- props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
- module.latestRemovedApiFilegroupName(apiScope))
- props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
-
- if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
- // Enable api lint.
- props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
- props.Check_api.Api_lint.New_since = latestApiFilegroupName
-
- // If it exists then pass a lint-baseline.txt through to droidstubs.
- baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
- baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
- paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
- if err != nil {
- mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
- }
- if len(paths) == 1 {
- props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
- } else if len(paths) != 0 {
- mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
- }
+ // List of APIs identified from the provided source files are created. They are later
+ // compared against to the not-yet-released (a.k.a current) list of APIs and to the
+ // last-released (a.k.a numbered) list of API.
+ currentApiFileName := apiScope.apiFilePrefix + "current.txt"
+ removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
+ apiDir := module.getApiDir()
+ currentApiFileName = path.Join(apiDir, currentApiFileName)
+ removedApiFileName = path.Join(apiDir, removedApiFileName)
+
+ // check against the not-yet-release API
+ props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
+ props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
+
+ if !apiScope.unstable {
+ // check against the latest released API
+ latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
+ props.Check_api.Last_released.Api_file = latestApiFilegroupName
+ props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
+ module.latestRemovedApiFilegroupName(apiScope))
+ props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
+
+ if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
+ // Enable api lint.
+ props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
+ props.Check_api.Api_lint.New_since = latestApiFilegroupName
+
+ // If it exists then pass a lint-baseline.txt through to droidstubs.
+ baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
+ baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
+ paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
+ if err != nil {
+ mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
+ }
+ if len(paths) == 1 {
+ props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
+ } else if len(paths) != 0 {
+ mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
}
}
+ }
- // Dist the api txt artifact for sdk builds.
- if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
- props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
- }
+ // Dist the api txt artifact for sdk builds.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
+ props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
}
mctx.CreateModule(DroidstubsFactory, &props)
@@ -1393,22 +1388,22 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and
return android.Paths{jarPath.Path()}
}
-// Get the apex name for module, "" if it is for platform.
-func getApexNameForModule(module android.Module) string {
+// Get the apex names for module, nil if it is for platform.
+func getApexNamesForModule(module android.Module) []string {
if apex, ok := module.(android.ApexModule); ok {
- return apex.ApexName()
+ return apex.InApexes()
}
- return ""
+ return nil
}
-// Check to see if the other module is within the same named APEX as this module.
+// Check to see if the other module is within the same set of named APEXes as this module.
//
// If either this or the other module are on the platform then this will return
// false.
-func withinSameApexAs(module android.ApexModule, other android.Module) bool {
- name := module.ApexName()
- return name != "" && getApexNameForModule(other) == name
+func withinSameApexesAs(module android.ApexModule, other android.Module) bool {
+ names := module.InApexes()
+ return len(names) > 0 && reflect.DeepEqual(names, getApexNamesForModule(other))
}
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
@@ -1427,7 +1422,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS
// Only allow access to the implementation library in the following condition:
// * No sdk_version specified on the referencing module.
// * The referencing module is in the same apex as this.
- if sdkVersion.kind == sdkPrivate || withinSameApexAs(module, ctx.Module()) {
+ if sdkVersion.kind == sdkPrivate || withinSameApexesAs(module, ctx.Module()) {
if headerJars {
return module.HeaderJars()
} else {
@@ -1520,22 +1515,8 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
}
for _, scope := range generatedScopes {
- stubsSourceArgs := scope.droidstubsArgsForGeneratingStubsSource
- stubsSourceModuleName := module.stubsSourceModuleName(scope)
-
- // If the args needed to generate the stubs and API are the same then they
- // can be generated in a single invocation of metalava, otherwise they will
- // need separate invocations.
- if scope.createStubsSourceAndApiTogether {
- // Use the stubs source name for legacy reasons.
- module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, true, stubsSourceArgs)
- } else {
- module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, false, stubsSourceArgs)
-
- apiArgs := scope.droidstubsArgsForGeneratingApi
- apiName := module.apiModuleName(scope)
- module.createStubsSourcesAndApi(mctx, scope, apiName, false, true, apiArgs)
- }
+ // Use the stubs source name for legacy reasons.
+ module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
module.createStubsLibrary(mctx, scope)
}
@@ -1824,7 +1805,7 @@ func (module *SdkLibraryImport) Name() string {
func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
// If the build is configured to use prebuilts then force this to be preferred.
- if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
+ if mctx.Config().AlwaysUsePrebuiltSdks() {
module.prebuilt.ForcePrefer()
}
@@ -1882,20 +1863,26 @@ func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.Defaulta
props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
}
-func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+// 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 {
if len(scopeProperties.Jars) == 0 {
continue
}
// Add dependencies to the prebuilt stubs library
- ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
+ ctx.AddVariationDependencies(nil, apiScope.stubsTag, "prebuilt_"+module.stubsLibraryModuleName(apiScope))
if len(scopeProperties.Stub_srcs) > 0 {
// Add dependencies to the prebuilt stubs source library
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, "prebuilt_"+module.stubsSourceModuleName(apiScope))
}
}
+}
+
+// Add other dependencies as normal.
+func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
implName := module.implLibraryModuleName()
if ctx.OtherModuleExists(implName) {
@@ -1920,6 +1907,11 @@ func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext,
return false
}
+func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ // we don't check prebuilt modules for sdk_version
+ return nil
+}
+
func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
return module.commonOutputFiles(tag)
}
@@ -1969,7 +1961,7 @@ func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersio
// For consistency with SdkLibrary make the implementation jar available to libraries that
// are within the same APEX.
implLibraryModule := module.implLibraryModule
- if implLibraryModule != nil && withinSameApexAs(module, ctx.Module()) {
+ if implLibraryModule != nil && withinSameApexesAs(module, ctx.Module()) {
if headerJars {
return implLibraryModule.HeaderJars()
} else {
@@ -1992,12 +1984,21 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont
return module.sdkJars(ctx, sdkVersion, false)
}
-// to satisfy apex.javaDependency interface
-func (module *SdkLibraryImport) DexJar() android.Path {
+// to satisfy SdkLibraryDependency interface
+func (module *SdkLibraryImport) DexJarBuildPath() android.Path {
+ if module.implLibraryModule == nil {
+ return nil
+ } else {
+ return module.implLibraryModule.DexJarBuildPath()
+ }
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *SdkLibraryImport) DexJarInstallPath() android.Path {
if module.implLibraryModule == nil {
return nil
} else {
- return module.implLibraryModule.DexJar()
+ return module.implLibraryModule.DexJarInstallPath()
}
}
@@ -2011,6 +2012,15 @@ func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
}
// to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) LintDepSets() LintDepSets {
+ if module.implLibraryModule == nil {
+ return LintDepSets{}
+ } else {
+ return module.implLibraryModule.LintDepSets()
+ }
+}
+
+// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()
}
@@ -2067,6 +2077,17 @@ func sdkLibraryXmlFactory() android.Module {
return module
}
+func (module *sdkLibraryXml) UniqueApexVariations() bool {
+ // sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
+ // mounted APEX, which contains the name of the APEX.
+ return true
+}
+
+// from android.PrebuiltEtcModule
+func (module *sdkLibraryXml) BaseDir() string {
+ return "etc"
+}
+
// from android.PrebuiltEtcModule
func (module *sdkLibraryXml) SubDir() string {
return "permissions"
@@ -2086,11 +2107,16 @@ func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
// do nothing
}
+func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error {
+ // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
+ return nil
+}
+
// File path to the runtime implementation library
func (module *sdkLibraryXml) implPath() string {
implName := proptools.String(module.properties.Lib_name)
- if apexName := module.ApexName(); apexName != "" {
- // TODO(b/146468504): ApexName() is only a soong module name, not apex name.
+ if apexName := module.ApexVariationName(); apexName != "" {
+ // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
// In most cases, this works fine. But when apex_name is set or override_apex is used
// this can be wrong.
return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName)
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 52d2df552..776069dc9 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -30,7 +30,6 @@ func TestClasspath(t *testing.T) {
var classpathTestcases = []struct {
name string
unbundled bool
- pdk bool
moduleType string
host android.OsClass
properties string
@@ -49,27 +48,27 @@ func TestClasspath(t *testing.T) {
}{
{
name: "default",
- bootclasspath: config.DefaultBootclasspathLibraries,
- system: config.DefaultSystemModules,
- java8classpath: config.DefaultLibraries,
- java9classpath: config.DefaultLibraries,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
+ java8classpath: config.FrameworkLibraries,
+ java9classpath: config.FrameworkLibraries,
aidl: "-Iframework/aidl",
},
{
name: `sdk_version:"core_platform"`,
properties: `sdk_version:"core_platform"`,
- bootclasspath: config.DefaultBootclasspathLibraries,
- system: config.DefaultSystemModules,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
java8classpath: []string{},
aidl: "",
},
{
name: "blank sdk version",
properties: `sdk_version: "",`,
- bootclasspath: config.DefaultBootclasspathLibraries,
- system: config.DefaultSystemModules,
- java8classpath: config.DefaultLibraries,
- java9classpath: config.DefaultLibraries,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
+ java8classpath: config.FrameworkLibraries,
+ java9classpath: config.FrameworkLibraries,
aidl: "-Iframework/aidl",
},
{
@@ -139,11 +138,10 @@ func TestClasspath(t *testing.T) {
},
{
- name: "core_current",
- properties: `sdk_version: "core_current",`,
- bootclasspath: []string{"core.current.stubs", "core-lambda-stubs"},
- system: "core-current-stubs-system-modules",
- java9classpath: []string{"core.current.stubs"},
+ name: "core_current",
+ properties: `sdk_version: "core_current",`,
+ bootclasspath: []string{"core.current.stubs", "core-lambda-stubs"},
+ system: "core-current-stubs-system-modules",
},
{
@@ -156,9 +154,9 @@ func TestClasspath(t *testing.T) {
{
name: "nostdlib system_modules",
- properties: `sdk_version: "none", system_modules: "core-platform-api-stubs-system-modules"`,
- system: "core-platform-api-stubs-system-modules",
- bootclasspath: []string{"core-platform-api-stubs-system-modules-lib"},
+ properties: `sdk_version: "none", system_modules: "stable-core-platform-api-stubs-system-modules"`,
+ system: "stable-core-platform-api-stubs-system-modules",
+ bootclasspath: []string{"stable-core-platform-api-stubs-system-modules-lib"},
java8classpath: []string{},
},
{
@@ -218,35 +216,6 @@ func TestClasspath(t *testing.T) {
},
{
- name: "pdk default",
- pdk: true,
- bootclasspath: []string{`""`},
- system: "sdk_public_30_system_modules",
- java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- aidl: "-pprebuilts/sdk/30/public/framework.aidl",
- },
- {
- name: "pdk current",
- pdk: true,
- properties: `sdk_version: "current",`,
- bootclasspath: []string{`""`},
- system: "sdk_public_30_system_modules",
- java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- aidl: "-pprebuilts/sdk/30/public/framework.aidl",
- },
- {
- name: "pdk 29",
- pdk: true,
- properties: `sdk_version: "29",`,
- bootclasspath: []string{`""`},
- system: "sdk_public_30_system_modules",
- java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
- aidl: "-pprebuilts/sdk/30/public/framework.aidl",
- },
- {
name: "module_current",
properties: `sdk_version: "module_current",`,
bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
@@ -385,9 +354,7 @@ func TestClasspath(t *testing.T) {
config := testConfig(nil, bpJava8, nil)
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
- }
- if testcase.pdk {
- config.TestProductVariables.Pdk = proptools.BoolPtr(true)
+ config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}
ctx := testContext()
run(t, ctx, config)
@@ -408,9 +375,7 @@ func TestClasspath(t *testing.T) {
config := testConfig(nil, bp, nil)
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
- }
- if testcase.pdk {
- config.TestProductVariables.Pdk = proptools.BoolPtr(true)
+ config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}
ctx := testContext()
run(t, ctx, config)
@@ -434,9 +399,7 @@ func TestClasspath(t *testing.T) {
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
- }
- if testcase.pdk {
- config.TestProductVariables.Pdk = proptools.BoolPtr(true)
+ config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}
ctx := testContext()
run(t, ctx, config)
@@ -452,9 +415,7 @@ func TestClasspath(t *testing.T) {
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
- }
- if testcase.pdk {
- config.TestProductVariables.Pdk = proptools.BoolPtr(true)
+ config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}
ctx := testContext()
run(t, ctx, config)
diff --git a/java/testing.go b/java/testing.go
index 48e449f34..70c857f39 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -16,9 +16,15 @@ package java
import (
"fmt"
+ "reflect"
+ "sort"
+ "testing"
"android/soong/android"
"android/soong/cc"
+ "android/soong/python"
+
+ "github.com/google/blueprint"
)
func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) android.Config {
@@ -38,6 +44,9 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
"prebuilts/sdk/17/public/android.jar": nil,
"prebuilts/sdk/17/public/framework.aidl": nil,
"prebuilts/sdk/17/system/android.jar": nil,
+ "prebuilts/sdk/28/public/android.jar": nil,
+ "prebuilts/sdk/28/public/framework.aidl": nil,
+ "prebuilts/sdk/28/system/android.jar": nil,
"prebuilts/sdk/29/public/android.jar": nil,
"prebuilts/sdk/29/public/framework.aidl": nil,
"prebuilts/sdk/29/system/android.jar": nil,
@@ -81,12 +90,15 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
+ "bin.py": nil,
+ python.StubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
+ MAIN_FILE = '%main%'`),
+
// For java_sdk_library
- "api/module-lib-current.txt": nil,
- "api/module-lib-removed.txt": nil,
- "api/system-server-current.txt": nil,
- "api/system-server-removed.txt": nil,
- "build/soong/scripts/gen-java-current-api-files.sh": nil,
+ "api/module-lib-current.txt": nil,
+ "api/module-lib-removed.txt": nil,
+ "api/system-server-current.txt": nil,
+ "api/system-server-removed.txt": nil,
}
cc.GatherRequiredFilesForTest(mockFS)
@@ -118,7 +130,8 @@ func GatherRequiredDepsForTest() string {
"android_module_lib_stubs_current",
"android_system_server_stubs_current",
"core.current.stubs",
- "core.platform.api.stubs",
+ "legacy.core.platform.api.stubs",
+ "stable.core.platform.api.stubs",
"kotlin-stdlib",
"kotlin-stdlib-jdk7",
"kotlin-stdlib-jdk8",
@@ -131,7 +144,7 @@ func GatherRequiredDepsForTest() string {
name: "%s",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
}
`, extra)
}
@@ -141,7 +154,7 @@ func GatherRequiredDepsForTest() string {
name: "framework",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
aidl: {
export_include_dirs: ["framework/aidl"],
},
@@ -156,7 +169,7 @@ func GatherRequiredDepsForTest() string {
name: "android.hidl.base-V1.0-java",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -164,7 +177,7 @@ func GatherRequiredDepsForTest() string {
name: "android.hidl.manager-V1.0-java",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -172,14 +185,31 @@ func GatherRequiredDepsForTest() string {
name: "org.apache.http.legacy",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
+ installable: true,
+ }
+
+ java_library {
+ name: "android.test.base",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
+ installable: true,
+ }
+
+ java_library {
+ name: "android.test.mock",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
`
systemModules := []string{
"core-current-stubs-system-modules",
- "core-platform-api-stubs-system-modules",
+ "legacy-core-platform-api-stubs-system-modules",
+ "stable-core-platform-api-stubs-system-modules",
}
for _, extra := range systemModules {
@@ -198,3 +228,17 @@ func GatherRequiredDepsForTest() string {
return bp
}
+
+func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
+ module := ctx.ModuleForTests(name, variant).Module()
+ deps := []string{}
+ ctx.VisitDirectDeps(module, func(m blueprint.Module) {
+ deps = append(deps, m.Name())
+ })
+ sort.Strings(deps)
+
+ if actual := deps; !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected %#q, found %#q", expected, actual)
+ }
+}