Merge "[Rust] Remove unused variables and deduplicate."
diff --git a/android/config.go b/android/config.go
index e1d597a..a53f44a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1029,6 +1029,27 @@
return Bool(c.config.productVariables.SamplingPGO)
}
+// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
+// path. Coverage is enabled by default when the product variable
+// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
+// enabled for any path which is part of this variable (and not part of the
+// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths
+// represents any path.
+func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool {
+ coverage := false
+ if c.config.productVariables.JavaCoveragePaths == nil ||
+ InList("*", c.config.productVariables.JavaCoveragePaths) ||
+ HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) {
+ coverage = true
+ }
+ if coverage && c.config.productVariables.JavaCoverageExcludePaths != nil {
+ if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) {
+ coverage = false
+ }
+ }
+ return coverage
+}
+
func (c *config) NativeLineCoverage() bool {
return Bool(c.productVariables.NativeLineCoverage)
}
diff --git a/android/variable.go b/android/variable.go
index 4440cee..863fe5a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -266,6 +266,9 @@
SamplingPGO *bool `json:",omitempty"`
+ JavaCoveragePaths []string `json:",omitempty"`
+ JavaCoverageExcludePaths []string `json:",omitempty"`
+
NativeLineCoverage *bool `json:",omitempty"`
Native_coverage *bool `json:",omitempty"`
ClangCoverage *bool `json:",omitempty"`
diff --git a/androidmk/androidmk/androidmk.go b/androidmk/androidmk/androidmk.go
index 9d0c3ac..4aadbe8 100644
--- a/androidmk/androidmk/androidmk.go
+++ b/androidmk/androidmk/androidmk.go
@@ -124,6 +124,7 @@
var conds []*conditional
var assignmentCond *conditional
+ var tree *bpparser.File
for _, node := range nodes {
file.setMkPos(p.Unpack(node.Pos()), p.Unpack(node.End()))
@@ -200,24 +201,27 @@
}
}
- tree := &bpparser.File{
+ tree = &bpparser.File{
Defs: file.defs,
Comments: file.comments,
}
// check for common supported but undesirable structures and clean them up
fixer := bpfix.NewFixer(tree)
- tree, err := fixer.Fix(bpfix.NewFixRequest().AddAll())
- if err != nil {
- return "", []error{err}
+ fixedTree, fixerErr := fixer.Fix(bpfix.NewFixRequest().AddAll())
+ if fixerErr != nil {
+ errs = append(errs, fixerErr)
+ } else {
+ tree = fixedTree
}
out, err := bpparser.Print(tree)
if err != nil {
- return "", []error{err}
+ errs = append(errs, err)
+ return "", errs
}
- return string(out), nil
+ return string(out), errs
}
func handleAssignment(file *bpFile, assignment *mkparser.Assignment, c *conditional) {
diff --git a/androidmk/cmd/androidmk.go b/androidmk/cmd/androidmk.go
index 00488eb..d2f4324 100644
--- a/androidmk/cmd/androidmk.go
+++ b/androidmk/cmd/androidmk.go
@@ -45,12 +45,13 @@
}
output, errs := androidmk.ConvertFile(os.Args[1], bytes.NewBuffer(b))
+ if len(output) > 0 {
+ fmt.Print(output)
+ }
if len(errs) > 0 {
for _, err := range errs {
fmt.Fprintln(os.Stderr, "ERROR: ", err)
}
os.Exit(1)
}
-
- fmt.Print(output)
}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 774b62d..91a405c 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -233,8 +233,9 @@
for _, o := range a.overridableProperties.Overrides {
patterns = append(patterns, "%."+o+a.suffix)
}
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " "))
-
+ if len(patterns) > 0 {
+ fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " "))
+ }
if len(a.compatSymlinks) > 0 {
// For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
@@ -307,7 +308,9 @@
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix())
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
+ if len(a.overridableProperties.Overrides) > 0 {
+ fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
+ }
if len(moduleNames) > 0 {
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
}
diff --git a/apex/apex.go b/apex/apex.go
index 3fef1ee..ce5d663 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -178,12 +178,6 @@
//
// Module separator
//
- m["com.android.conscrypt"] = []string{
- "libnativehelper_header_only",
- }
- //
- // Module separator
- //
m["com.android.neuralnetworks"] = []string{
"android.hardware.neuralnetworks@1.0",
"android.hardware.neuralnetworks@1.1",
@@ -479,7 +473,6 @@
"libbase_ndk",
"libfuse",
"libfuse_jni",
- "libnativehelper_header_only",
}
//
// Module separator
@@ -561,7 +554,6 @@
"ipmemorystore-aidl-interfaces-java",
"libcgrouprc",
"libcgrouprc_format",
- "libnativehelper_compat_libc++",
"libtetherutilsjni",
"libvndksupport",
"net-utils-framework-common",
@@ -994,7 +986,7 @@
Uses []string
// A txt file containing list of files that are allowed to be included in this APEX.
- Whitelisted_files *string
+ Allowed_files *string
// package format of this apex variant; could be non-flattened, flattened, or zip.
// imageApex, zipApex or flattened
@@ -1954,8 +1946,10 @@
fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
fi.isJniLib = isJniLib
filesInfo = append(filesInfo, fi)
- // bootstrap bionic libs are treated as provided by system
- if c.HasStubsVariants() && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
+ // Collect the list of stub-providing libs except:
+ // - VNDK libs are only for vendors
+ // - bootstrap bionic libs are treated as provided by system
+ if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
provideNativeLibs = append(provideNativeLibs, fi.Stem())
}
return true // track transitive dependencies
@@ -1981,7 +1975,7 @@
}
case javaLibTag:
switch child.(type) {
- case *java.Library, *java.SdkLibrary, *java.DexImport:
+ case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport:
af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7159a45..a7a7765 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -66,7 +66,7 @@
func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
t.Helper()
ctx, config := testApexContext(t, bp, handlers...)
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ _, errs := ctx.ParseBlueprintsFiles(".")
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
@@ -217,6 +217,11 @@
}
ctx := android.NewTestArchContext()
+
+ // from android package
+ android.RegisterPackageBuildComponents(ctx)
+ ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
+
ctx.RegisterModuleType("apex", BundleFactory)
ctx.RegisterModuleType("apex_test", testApexBundleFactory)
ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
@@ -230,6 +235,12 @@
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
cc.RegisterRequiredBuildComponentsForTest(ctx)
+
+ // Register this after the prebuilt mutators have been registered (in
+ // cc.RegisterRequiredBuildComponentsForTest) to match what happens at runtime.
+ ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
+ ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
+
ctx.RegisterModuleType("cc_test", cc.TestFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
@@ -240,7 +251,7 @@
java.RegisterJavaBuildComponents(ctx)
java.RegisterSystemModulesBuildComponents(ctx)
java.RegisterAppBuildComponents(ctx)
- ctx.RegisterModuleType("java_sdk_library", java.SdkLibraryFactory)
+ java.RegisterSdkLibraryBuildComponents(ctx)
ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory)
ctx.PreDepsMutators(RegisterPreDepsMutators)
@@ -2817,6 +2828,40 @@
})
}
+func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex_vndk {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: ":myapex-file_contexts",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libz",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ stubs: {
+ symbol_file: "libz.map.txt",
+ versions: ["30"],
+ }
+ }
+ `+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{
+ "libz.map.txt": nil,
+ }))
+
+ apexManifestRule := ctx.ModuleForTests("myapex", "android_common_image").Rule("apexManifestRule")
+ provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
+ ensureListEmpty(t, provideNativeLibs)
+}
+
func TestDependenciesInApexManifest(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@@ -4332,6 +4377,9 @@
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
+
+ // For java_sdk_library_import
+ "a.jar": nil,
}
func TestJavaSDKLibrary(t *testing.T) {
@@ -4458,6 +4506,117 @@
}
}
+func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
+ ctx, _ := testApex(t, ``,
+ withFiles(map[string][]byte{
+ "apex/a.java": nil,
+ "apex/apex_manifest.json": nil,
+ "apex/Android.bp": []byte(`
+ package {
+ default_visibility: ["//visibility:private"],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["foo", "bar"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+`),
+ "source/a.java": nil,
+ "source/api/current.txt": nil,
+ "source/api/removed.txt": nil,
+ "source/Android.bp": []byte(`
+ package {
+ default_visibility: ["//visibility:private"],
+ }
+
+ java_sdk_library {
+ name: "foo",
+ visibility: ["//apex"],
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ }
+`),
+ "prebuilt/a.jar": nil,
+ "prebuilt/Android.bp": []byte(`
+ package {
+ default_visibility: ["//visibility:private"],
+ }
+
+ java_sdk_library_import {
+ name: "foo",
+ visibility: ["//apex", "//source"],
+ apex_available: ["myapex"],
+ prefer: true,
+ public: {
+ jars: ["a.jar"],
+ },
+ }
+`),
+ }),
+ )
+
+ // java_sdk_library installs both impl jar and permission XML
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "javalib/bar.jar",
+ "javalib/foo.jar",
+ "etc/permissions/foo.xml",
+ })
+
+ // The bar library should depend on the implementation jar.
+ barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
+ if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected %q, found %#q", expected, actual)
+ }
+}
+
+func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
+ testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["foo"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library_import {
+ name: "foo",
+ apex_available: ["myapex"],
+ prefer: true,
+ public: {
+ jars: ["a.jar"],
+ },
+ }
+
+ `, withFiles(filesForSdkLibrary))
+}
+
func TestCompatConfig(t *testing.T) {
ctx, _ := testApex(t, `
apex {
diff --git a/apex/builder.go b/apex/builder.go
index 1293588..53c1193 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -391,7 +391,7 @@
emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String())
implicitInputs = append(implicitInputs, a.manifestPbOut)
- if a.properties.Whitelisted_files != nil {
+ if a.properties.Allowed_files != nil {
ctx.Build(pctx, android.BuildParams{
Rule: emitApexContentRule,
Implicits: implicitInputs,
@@ -402,7 +402,7 @@
},
})
implicitInputs = append(implicitInputs, imageContentFile)
- allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Whitelisted_files))
+ allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Allowed_files))
phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
ctx.Build(pctx, android.BuildParams{
diff --git a/cc/cc.go b/cc/cc.go
index f80c229..ebdb46c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3099,10 +3099,19 @@
}
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
// This will be available in /vendor (or /odm) only
- // We assume that modules under proprietary paths are compatible for
- // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
- // PLATFORM_VNDK_VERSION.
- if isVendorProprietaryPath(mctx.ModuleDir()) {
+
+ // kernel_headers is a special module type whose exported headers
+ // are coming from DeviceKernelHeaders() which is always vendor
+ // dependent. They'll always have both vendor variants.
+ // For other modules, we assume that modules under proprietary
+ // paths are compatible for BOARD_VNDK_VERSION. The other modules
+ // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
+ if _, ok := m.linker.(*kernelHeadersDecorator); ok {
+ vendorVariants = append(vendorVariants,
+ platformVndkVersion,
+ boardVndkVersion,
+ )
+ } else if isVendorProprietaryPath(mctx.ModuleDir()) {
vendorVariants = append(vendorVariants, boardVndkVersion)
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
@@ -3200,6 +3209,10 @@
}
}
+func (c *Module) IsSdkVariant() bool {
+ return c.Properties.IsSdkVariant
+}
+
func getCurrentNdkPrebuiltVersion(ctx DepsContext) string {
if ctx.Config().PlatformSdkVersionInt() > config.NdkMaxPrebuiltVersionInt {
return strconv.Itoa(config.NdkMaxPrebuiltVersionInt)
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 9383463..62d8cc8 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -32,7 +32,7 @@
"-march=armv8-a",
},
"armv8-2a": []string{
- "-march=armv8.2a",
+ "-march=armv8.2-a",
},
}
diff --git a/cc/library.go b/cc/library.go
index ba8b0f4..968702e 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1077,9 +1077,14 @@
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.shouldCreateSourceAbiDump(ctx) {
- vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
- if ver := ctx.DeviceConfig().VndkVersion(); ver != "" && ver != "current" {
- vndkVersion = ver
+ var vndkVersion string
+
+ if ctx.useVndk() {
+ // For modules linking against vndk, follow its vndk version
+ vndkVersion = ctx.Module().(*Module).VndkVersion()
+ } else {
+ // Regard the other modules as PLATFORM_VNDK_VERSION
+ vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
}
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1575,7 +1580,8 @@
// (which is unnamed) and zero or more stubs variants.
func VersionMutator(mctx android.BottomUpMutatorContext) {
if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
- if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
+ if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 &&
+ !library.IsSdkVariant() {
versions := library.StubsVersions()
normalizeVersions(mctx, versions)
if mctx.Failed() {
diff --git a/cc/linkable.go b/cc/linkable.go
index de36f90..66b1c3f 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -56,6 +56,7 @@
SdkVersion() string
AlwaysSdk() bool
+ IsSdkVariant() bool
ToolchainLibrary() bool
NdkPrebuiltStl() bool
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index d79badb..5ef9a78 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -329,6 +329,7 @@
Description: "parse ndk api symbol file for api coverage: " + symbolFilePath.Rel(),
Outputs: []android.WritablePath{parsedApiCoveragePath},
Input: symbolFilePath,
+ Implicits: []android.Path{apiLevelsJson},
Args: map[string]string{
"apiMap": apiLevelsJson.String(),
},
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index ea94544..4dad730 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -548,6 +548,10 @@
if !m.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() {
return false
}
+ // skip kernel_headers which always depend on vendor
+ if _, ok := m.linker.(*kernelHeadersDecorator); ok {
+ return false
+ }
// Libraries
if l, ok := m.linker.(snapshotLibraryInterface); ok {
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index d0cad78..c965107 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -171,7 +171,7 @@
buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
- defer build.UploadMetrics(buildCtx, config, buildStartedMilli, buildErrorFile, rbeMetricsFile, soongMetricsFile)
+ defer build.UploadMetrics(buildCtx, config, c.forceDumbOutput, buildStartedMilli, buildErrorFile, rbeMetricsFile, soongMetricsFile)
os.MkdirAll(logsDir, 0777)
log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
diff --git a/java/app.go b/java/app.go
index 0fdede1..74c92a6 100755
--- a/java/app.go
+++ b/java/app.go
@@ -133,7 +133,7 @@
// We are assuming here that the master 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 = ctx.ModuleName() + ".apk"
+ as.masterFile = as.BaseModuleName() + ".apk"
screenDensities := "all"
if dpis := ctx.Config().ProductAAPTPrebuiltDPI(); len(dpis) > 0 {
screenDensities = strings.ToUpper(strings.Join(dpis, ","))
diff --git a/java/java.go b/java/java.go
index 1cdfbf1..bd5f6b7 100644
--- a/java/java.go
+++ b/java/java.go
@@ -601,7 +601,9 @@
}
func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
- return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
+ return j.properties.Instrument &&
+ ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
+ ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
}
func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
@@ -610,6 +612,21 @@
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))
}
@@ -1150,9 +1167,9 @@
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")
@@ -1543,11 +1560,7 @@
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
}
diff --git a/java/java_test.go b/java/java_test.go
index 215070e..1d07e70 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -466,7 +466,41 @@
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, sanity 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) {
@@ -1448,6 +1482,38 @@
`)
}
+func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
+ testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java", "b.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+ `)
+}
+
+func TestJavaSdkLibrary_SystemServer(t *testing.T) {
+ testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java", "b.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ system_server: {
+ enabled: true,
+ },
+ }
+ `)
+}
+
func TestJavaSdkLibrary_MissingScope(t *testing.T) {
testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, `
java_sdk_library {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index de5ee03..503ad59 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -264,7 +264,7 @@
apiScopeModuleLib = initApiScope(&apiScope{
name: "module-lib",
extends: apiScopeSystem,
- // Module_lib scope is disabled by default in legacy mode.
+ // The module-lib scope is disabled by default in legacy mode.
//
// Enabling this would break existing usages.
legacyEnabledStatus: func(module *SdkLibrary) bool {
@@ -280,11 +280,34 @@
"--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
},
})
+ apiScopeSystemServer = initApiScope(&apiScope{
+ name: "system-server",
+ extends: apiScopePublic,
+ // The system-server scope is disabled by default in legacy mode.
+ //
+ // Enabling this would break existing usages.
+ legacyEnabledStatus: func(module *SdkLibrary) bool {
+ return false
+ },
+ scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+ return &module.sdkLibraryProperties.System_server
+ },
+ 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",
+ // com.android.* classes are okay in this interface"
+ "--hide InternalClasses",
+ },
+ })
allApiScopes = apiScopes{
apiScopePublic,
apiScopeSystem,
apiScopeTest,
apiScopeModuleLib,
+ apiScopeSystemServer,
}
)
@@ -429,12 +452,18 @@
// In non-legacy mode the test api scope is disabled by default.
Test ApiScopeProperties
- // The properties specific to the module_lib api scope
+ // The properties specific to the module-lib api scope
//
- // Unless explicitly specified by using test.enabled the module_lib api scope is
+ // Unless explicitly specified by using test.enabled the module-lib api scope is
// disabled by default.
Module_lib ApiScopeProperties
+ // The properties specific to the system-server api scope
+ //
+ // Unless explicitly specified by using test.enabled the module-lib api scope is
+ // disabled by default.
+ System_server ApiScopeProperties
+
// Determines if the stubs are preferred over the implementation library
// for linking, even when the client doesn't specify sdk_version. When this
// is set to true, such clients are provided with the widest API surface that
@@ -600,6 +629,16 @@
return true
}
+// Module name of the runtime implementation library
+func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
+ return c.moduleBase.BaseModuleName() + ".impl"
+}
+
+// Module name of the XML file for the lib
+func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
+ return c.moduleBase.BaseModuleName() + sdkXmlFileSuffix
+}
+
// Name of the java_library module that compiles the stubs source.
func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
return c.namingScheme.stubsLibraryModuleName(apiScope, c.moduleBase.BaseModuleName())
@@ -743,6 +782,8 @@
apiScope = apiScopeModuleLib
case sdkTest:
apiScope = apiScopeTest
+ case sdkSystemServer:
+ apiScope = apiScopeSystemServer
default:
apiScope = apiScopePublic
}
@@ -827,7 +868,7 @@
var _ SdkLibraryComponentDependency = (*Library)(nil)
var _ SdkLibraryComponentDependency = (*Import)(nil)
var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
-var _ SdkLibraryComponentDependency = (*sdkLibraryImport)(nil)
+var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil)
// Provides access to sdk_version related header and implentation jars.
type SdkLibraryDependency interface {
@@ -913,16 +954,24 @@
return generatedScopes
}
-var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"}
+type sdkLibraryComponentTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t sdkLibraryComponentTag) ExcludeFromVisibilityEnforcement() {}
+
+var xmlPermissionsFileTag = sdkLibraryComponentTag{name: "xml-permissions-file"}
func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
- if dt, ok := depTag.(dependencyTag); ok {
+ if dt, ok := depTag.(sdkLibraryComponentTag); ok {
return dt == xmlPermissionsFileTag
}
return false
}
-var implLibraryTag = dependencyTag{name: "impl-library"}
+var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}
func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, apiScope := range module.getGeneratedApiScopes(ctx) {
@@ -947,7 +996,7 @@
if module.sharedLibrary() {
// Add dependency to the rule for generating the xml permissions file
- ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
+ ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName())
}
// Only add the deps for the library if it is actually going to be built.
@@ -994,20 +1043,10 @@
}
entriesList := module.Library.AndroidMkEntries()
entries := &entriesList[0]
- entries.Required = append(entries.Required, module.xmlFileName())
+ entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
return entriesList
}
-// Module name of the runtime implementation library
-func (module *SdkLibrary) implLibraryModuleName() string {
- return module.BaseModuleName() + ".impl"
-}
-
-// Module name of the XML file for the lib
-func (module *SdkLibrary) xmlFileName() string {
- return module.BaseModuleName() + sdkXmlFileSuffix
-}
-
// The dist path of the stub artifacts
func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
if module.ModuleBase.Owner() != "" {
@@ -1298,7 +1337,7 @@
Lib_name *string
Apex_available []string
}{
- Name: proptools.StringPtr(module.xmlFileName()),
+ Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
Lib_name: proptools.StringPtr(module.BaseModuleName()),
Apex_available: module.ApexProperties.Apex_available,
}
@@ -1346,7 +1385,7 @@
//
// If either this or the other module are on the platform then this will return
// false.
-func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
+func withinSameApexAs(module android.ApexModule, other android.Module) bool {
name := module.ApexName()
return name != "" && getApexNameForModule(other) == name
}
@@ -1367,7 +1406,7 @@
// 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 || module.withinSameApexAs(ctx.Module()) {
+ if sdkVersion.kind == sdkPrivate || withinSameApexAs(module, ctx.Module()) {
if headerJars {
return module.HeaderJars()
} else {
@@ -1671,7 +1710,7 @@
Libs []string
}
-type sdkLibraryImport struct {
+type SdkLibraryImport struct {
android.ModuleBase
android.DefaultableModuleBase
prebuilt android.Prebuilt
@@ -1684,9 +1723,17 @@
scopeProperties map[*apiScope]*sdkLibraryScopeProperties
commonToSdkLibraryAndImport
+
+ // The reference to the implementation library created by the source module.
+ // Is nil if the source module does not exist.
+ implLibraryModule *Library
+
+ // The reference to the xml permissions module created by the source module.
+ // Is nil if the source module does not exist.
+ xmlPermissionsFileModule *sdkLibraryXml
}
-var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
+var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)
// The type of a structure that contains a field of type sdkLibraryScopeProperties
// for each apiscope in allApiScopes, e.g. something like:
@@ -1728,7 +1775,7 @@
// java_sdk_library_import imports a prebuilt java_sdk_library.
func sdkLibraryImportFactory() android.Module {
- module := &sdkLibraryImport{}
+ module := &SdkLibraryImport{}
allScopeProperties, scopeToProperties := createPropertiesInstance()
module.scopeProperties = scopeToProperties
@@ -1750,15 +1797,15 @@
return module
}
-func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
+func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt {
return &module.prebuilt
}
-func (module *sdkLibraryImport) Name() string {
+func (module *SdkLibraryImport) Name() string {
return module.prebuilt.Name(module.ModuleBase.Name())
}
-func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
+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() {
@@ -1783,7 +1830,7 @@
*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
}
-func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
// Creates a java import for the jar with ".stubs" suffix
props := struct {
Name *string
@@ -1805,7 +1852,7 @@
mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
-func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
props := struct {
Name *string
Srcs []string
@@ -1819,7 +1866,7 @@
props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
}
-func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
for apiScope, scopeProperties := range module.scopeProperties {
if len(scopeProperties.Jars) == 0 {
continue
@@ -1833,13 +1880,35 @@
ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
}
}
+
+ implName := module.implLibraryModuleName()
+ if ctx.OtherModuleExists(implName) {
+ ctx.AddVariationDependencies(nil, implLibraryTag, implName)
+
+ xmlPermissionsModuleName := module.xmlPermissionsModuleName()
+ if module.sharedLibrary() && ctx.OtherModuleExists(xmlPermissionsModuleName) {
+ // Add dependency to the rule for generating the xml permissions file
+ ctx.AddDependency(module, xmlPermissionsFileTag, xmlPermissionsModuleName)
+ }
+ }
}
-func (module *sdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
+func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
+ depTag := mctx.OtherModuleDependencyTag(dep)
+ if depTag == xmlPermissionsFileTag {
+ return true
+ }
+
+ // None of the other dependencies of the java_sdk_library_import are in the same apex
+ // as the one that references this module.
+ return false
+}
+
+func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
return module.commonOutputFiles(tag)
}
-func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Record the paths to the prebuilt stubs library and stubs source.
ctx.VisitDirectDeps(func(to android.Module) {
tag := ctx.OtherModuleDependencyTag(to)
@@ -1852,6 +1921,18 @@
// Extract information from the dependency. The exact information extracted
// is determined by the nature of the dependency which is determined by the tag.
scopeTag.extractDepInfo(ctx, to, scopePaths)
+ } else if tag == implLibraryTag {
+ if implLibrary, ok := to.(*Library); ok {
+ module.implLibraryModule = implLibrary
+ } else {
+ ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
+ }
+ } else if tag == xmlPermissionsFileTag {
+ if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
+ module.xmlPermissionsFileModule = xmlPermissionsFileModule
+ } else {
+ ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
+ }
}
})
@@ -1867,20 +1948,55 @@
}
}
-func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
+func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
+
+ // 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 headerJars {
+ return implLibraryModule.HeaderJars()
+ } else {
+ return implLibraryModule.ImplementationJars()
+ }
+ }
+
return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
+func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the prebuilt stubs.
- return module.sdkJars(ctx, sdkVersion)
+ return module.sdkJars(ctx, sdkVersion, true)
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
+func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
// This module is just a wrapper for the stubs.
- return module.sdkJars(ctx, sdkVersion)
+ return module.sdkJars(ctx, sdkVersion, false)
+}
+
+// to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) DexJarBuildPath() android.Path {
+ if module.implLibraryModule == nil {
+ return nil
+ } else {
+ return module.implLibraryModule.DexJarBuildPath()
+ }
+}
+
+// to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
+ if module.implLibraryModule == nil {
+ return nil
+ } else {
+ return module.implLibraryModule.JacocoReportClassesFile()
+ }
+}
+
+// to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) Stem() string {
+ return module.BaseModuleName()
}
//
diff --git a/java/testing.go b/java/testing.go
index f34c64a..6fc10da 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -80,6 +80,13 @@
"prebuilts/sdk/30/test/api/bar-removed.txt": nil,
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
+
+ // 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,
}
cc.GatherRequiredFilesForTest(mockFS)
diff --git a/rust/rust.go b/rust/rust.go
index 7412db1..7b82b1f 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -195,6 +195,10 @@
return false
}
+func (mod *Module) IsSdkVariant() bool {
+ return false
+}
+
func (mod *Module) ToolchainLibrary() bool {
return false
}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 56706c7..77a4e94 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -34,6 +34,8 @@
"api/test-removed.txt": 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,
"build/soong/scripts/gen-java-current-api-files.sh": nil,
}
@@ -61,6 +63,9 @@
name: "android_module_lib_stubs_current",
}
java_import {
+ name: "android_system_server_stubs_current",
+}
+java_import {
name: "core-lambda-stubs",
sdk_version: "none",
}
@@ -1398,6 +1403,93 @@
)
}
+func TestSnapshotWithJavaSdkLibrary_SystemServer(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_sdk_libs: ["myjavalib"],
+ }
+
+ java_sdk_library {
+ name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ srcs: ["Test.java"],
+ sdk_version: "current",
+ public: {
+ enabled: true,
+ },
+ system_server: {
+ enabled: true,
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system_server: {
+ jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
+ current_api: "sdk_library/system-server/myjavalib.txt",
+ removed_api: "sdk_library/system-server/myjavalib-removed.txt",
+ sdk_version: "system_server_current",
+ },
+}
+
+java_sdk_library_import {
+ name: "myjavalib",
+ prefer: false,
+ apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
+ public: {
+ jars: ["sdk_library/public/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+ current_api: "sdk_library/public/myjavalib.txt",
+ removed_api: "sdk_library/public/myjavalib-removed.txt",
+ sdk_version: "current",
+ },
+ system_server: {
+ jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
+ current_api: "sdk_library/system-server/myjavalib.txt",
+ removed_api: "sdk_library/system-server/myjavalib-removed.txt",
+ sdk_version: "system_server_current",
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ java_sdk_libs: ["mysdk_myjavalib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.system_server/android_common/javac/myjavalib.stubs.system_server.jar -> sdk_library/system-server/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system_server/android_common/myjavalib.stubs.source.system_server_api.txt -> sdk_library/system-server/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system_server/android_common/myjavalib.stubs.source.system_server_removed.txt -> sdk_library/system-server/myjavalib-removed.txt
+`),
+ checkMergeZips(
+ ".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
+ ".intermediates/mysdk/common_os/tmp/sdk_library/system-server/myjavalib_stub_sources.zip",
+ ),
+ )
+}
+
func TestSnapshotWithJavaSdkLibrary_NamingScheme(t *testing.T) {
result := testSdkWithJava(t, `
sdk {
diff --git a/ui/build/upload.go b/ui/build/upload.go
index 75a5e2f..3a23a80 100644
--- a/ui/build/upload.go
+++ b/ui/build/upload.go
@@ -23,6 +23,7 @@
"path/filepath"
"time"
+ "android/soong/ui/metrics"
"github.com/golang/protobuf/proto"
upload_proto "android/soong/ui/metrics/upload_proto"
@@ -32,11 +33,21 @@
uploadPbFilename = ".uploader.pb"
)
+var (
+ // For testing purpose
+ getTmpDir = ioutil.TempDir
+)
+
// UploadMetrics uploads a set of metrics files to a server for analysis. An
// uploader full path is required to be specified in order to upload the set
// of metrics files. This is accomplished by defining the ANDROID_ENABLE_METRICS_UPLOAD
-// environment variable.
-func UploadMetrics(ctx Context, config Config, buildStartedMilli int64, files ...string) {
+// environment variable. The metrics files are copied to a temporary directory
+// and the uploader is then executed in the background to allow the user to continue
+// working.
+func UploadMetrics(ctx Context, config Config, forceDumbOutput bool, buildStartedMilli int64, files ...string) {
+ ctx.BeginTrace(metrics.RunSetupTool, "upload_metrics")
+ defer ctx.EndTrace()
+
uploader := config.MetricsUploaderApp()
// No metrics to upload if the path to the uploader was not specified.
if uploader == "" {
@@ -56,6 +67,22 @@
return
}
+ // The temporary directory cannot be deleted as the metrics uploader is started
+ // in the background and requires to exist until the operation is done. The
+ // uploader can delete the directory as it is specified in the upload proto.
+ tmpDir, err := getTmpDir("", "upload_metrics")
+ if err != nil {
+ ctx.Fatalf("failed to create a temporary directory to store the list of metrics files: %v\n", err)
+ }
+
+ for i, src := range metricsFiles {
+ dst := filepath.Join(tmpDir, filepath.Base(src))
+ if _, err := copyFile(src, dst); err != nil {
+ ctx.Fatalf("failed to copy %q to %q: %v\n", src, dst, err)
+ }
+ metricsFiles[i] = dst
+ }
+
// For platform builds, the branch and target name is hardcoded to specific
// values for later extraction of the metrics in the data metrics pipeline.
data, err := proto.Marshal(&upload_proto.Upload{
@@ -64,17 +91,23 @@
BranchName: proto.String("developer-metrics"),
TargetName: proto.String("platform-build-systems-metrics"),
MetricsFiles: metricsFiles,
+ DirectoriesToDelete: []string{tmpDir},
})
if err != nil {
ctx.Fatalf("failed to marshal metrics upload proto buffer message: %v\n", err)
}
- pbFile := filepath.Join(config.OutDir(), uploadPbFilename)
+ pbFile := filepath.Join(tmpDir, uploadPbFilename)
if err := ioutil.WriteFile(pbFile, data, 0644); err != nil {
ctx.Fatalf("failed to write the marshaled metrics upload protobuf to %q: %v\n", pbFile, err)
}
- // Remove the upload file as it's not longer needed after it has been processed by the uploader.
- defer os.Remove(pbFile)
- Command(ctx, config, "upload metrics", uploader, "--upload-metrics", pbFile).RunAndStreamOrFatal()
+ // Start the uploader in the background as it takes several milliseconds to start the uploader
+ // and prepare the metrics for upload. This affects small commands like "lunch".
+ cmd := Command(ctx, config, "upload metrics", uploader, "--upload-metrics", pbFile)
+ if forceDumbOutput {
+ cmd.RunOrFatal()
+ } else {
+ cmd.RunAndStreamOrFatal()
+ }
}
diff --git a/ui/build/upload_test.go b/ui/build/upload_test.go
index adaa08d..c812730 100644
--- a/ui/build/upload_test.go
+++ b/ui/build/upload_test.go
@@ -15,6 +15,7 @@
package build
import (
+ "errors"
"io/ioutil"
"os"
"path/filepath"
@@ -61,6 +62,22 @@
}
defer os.RemoveAll(outDir)
+ // Supply our own getTmpDir to delete the temp dir once the test is done.
+ orgGetTmpDir := getTmpDir
+ getTmpDir = func(string, string) (string, error) {
+ retDir := filepath.Join(outDir, "tmp_upload_dir")
+ if err := os.Mkdir(retDir, 0755); err != nil {
+ t.Fatalf("failed to create temporary directory %q: %v", retDir, err)
+ }
+ return retDir, nil
+ }
+ defer func() { getTmpDir = orgGetTmpDir }()
+
+ metricsUploadDir := filepath.Join(outDir, ".metrics_uploader")
+ if err := os.Mkdir(metricsUploadDir, 0755); err != nil {
+ t.Fatalf("failed to create %q directory for oauth valid check: %v", metricsUploadDir, err)
+ }
+
var metricsFiles []string
if tt.createFiles {
for _, f := range tt.files {
@@ -80,41 +97,62 @@
buildDateTime: strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10),
}}
- UploadMetrics(ctx, config, 1591031903, metricsFiles...)
-
- if _, err := os.Stat(filepath.Join(outDir, uploadPbFilename)); err == nil {
- t.Error("got true, want false for upload protobuf file to exist")
- }
+ UploadMetrics(ctx, config, false, 1591031903, metricsFiles...)
})
}
}
func TestUploadMetricsErrors(t *testing.T) {
- expectedErr := "failed to write the marshaled"
- defer logger.Recover(func(err error) {
- got := err.Error()
- if !strings.Contains(got, expectedErr) {
- t.Errorf("got %q, want %q to be contained in error", got, expectedErr)
- }
- })
+ ctx := testContext()
+ tests := []struct {
+ description string
+ tmpDir string
+ tmpDirErr error
+ expectedErr string
+ }{{
+ description: "getTmpDir returned error",
+ tmpDirErr: errors.New("getTmpDir failed"),
+ expectedErr: "getTmpDir failed",
+ }, {
+ description: "copyFile operation error",
+ tmpDir: "/fake_dir",
+ expectedErr: "failed to copy",
+ }}
- outDir, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("failed to create out directory: %v", outDir)
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ defer logger.Recover(func(err error) {
+ got := err.Error()
+ if !strings.Contains(got, tt.expectedErr) {
+ t.Errorf("got %q, want %q to be contained in error", got, tt.expectedErr)
+ }
+ })
+
+ outDir, err := ioutil.TempDir("", "")
+ if err != nil {
+ t.Fatalf("failed to create out directory: %v", outDir)
+ }
+ defer os.RemoveAll(outDir)
+
+ orgGetTmpDir := getTmpDir
+ getTmpDir = func(string, string) (string, error) {
+ return tt.tmpDir, tt.tmpDirErr
+ }
+ defer func() { getTmpDir = orgGetTmpDir }()
+
+ metricsFile := filepath.Join(outDir, "metrics_file_1")
+ if err := ioutil.WriteFile(metricsFile, []byte("test file"), 0644); err != nil {
+ t.Fatalf("failed to create a fake metrics file %q for uploading: %v", metricsFile, err)
+ }
+
+ config := Config{&configImpl{
+ environ: &Environment{
+ "ANDROID_ENABLE_METRICS_UPLOAD=fake",
+ "OUT_DIR=/bad",
+ }}}
+
+ UploadMetrics(ctx, config, true, 1591031903, metricsFile)
+ t.Errorf("got nil, expecting %q as a failure", tt.expectedErr)
+ })
}
- defer os.RemoveAll(outDir)
-
- metricsFile := filepath.Join(outDir, "metrics_file_1")
- if err := ioutil.WriteFile(metricsFile, []byte("test file"), 0644); err != nil {
- t.Fatalf("failed to create a fake metrics file %q for uploading: %v", metricsFile, err)
- }
-
- config := Config{&configImpl{
- environ: &Environment{
- "ANDROID_ENABLE_METRICS_UPLOAD=fake",
- "OUT_DIR=/bad",
- }}}
-
- UploadMetrics(testContext(), config, 1591031903, metricsFile)
- t.Errorf("got nil, expecting %q as a failure", expectedErr)
}
diff --git a/ui/build/util.go b/ui/build/util.go
index 75e6753..d44cd6d 100644
--- a/ui/build/util.go
+++ b/ui/build/util.go
@@ -15,6 +15,7 @@
package build
import (
+ "io"
"os"
"path/filepath"
"strings"
@@ -124,3 +125,20 @@
}
return str[:idx], str[idx+1:], true
}
+
+// copyFile copies a file from src to dst. filepath.Dir(dst) must exist.
+func copyFile(src, dst string) (int64, error) {
+ source, err := os.Open(src)
+ if err != nil {
+ return 0, err
+ }
+ defer source.Close()
+
+ destination, err := os.Create(dst)
+ if err != nil {
+ return 0, err
+ }
+ defer destination.Close()
+
+ return io.Copy(destination, source)
+}
diff --git a/ui/build/util_test.go b/ui/build/util_test.go
index 89bfc77..b22e997 100644
--- a/ui/build/util_test.go
+++ b/ui/build/util_test.go
@@ -15,6 +15,7 @@
package build
import (
+ "bytes"
"io/ioutil"
"os"
"path/filepath"
@@ -49,3 +50,72 @@
ensureEmptyDirectoriesExist(ctx, filepath.Join(tmpDir, "a"))
}
+
+func TestCopyFile(t *testing.T) {
+ tmpDir, err := ioutil.TempDir("", "test_copy_file")
+ if err != nil {
+ t.Fatalf("failed to create temporary directory to hold test text files: %v", err)
+ }
+ defer os.Remove(tmpDir)
+
+ data := []byte("fake data")
+ src := filepath.Join(tmpDir, "src.txt")
+ if err := ioutil.WriteFile(src, data, 0755); err != nil {
+ t.Fatalf("failed to create a src file %q for copying: %v", src, err)
+ }
+
+ dst := filepath.Join(tmpDir, "dst.txt")
+
+ l, err := copyFile(src, dst)
+ if err != nil {
+ t.Fatalf("got %v, expecting nil error on copyFile operation", err)
+ }
+
+ if l != int64(len(data)) {
+ t.Errorf("got %d, expecting %d for copied bytes", l, len(data))
+ }
+
+ dstData, err := ioutil.ReadFile(dst)
+ if err != nil {
+ t.Fatalf("got %v, expecting nil error reading dst %q file", err, dst)
+ }
+
+ if bytes.Compare(data, dstData) != 0 {
+ t.Errorf("got %q, expecting data %q from dst %q text file", string(data), string(dstData), dst)
+ }
+}
+
+func TestCopyFileErrors(t *testing.T) {
+ tmpDir, err := ioutil.TempDir("", "test_copy_file_errors")
+ if err != nil {
+ t.Fatalf("failed to create temporary directory to hold test text files: %v", err)
+ }
+ defer os.Remove(tmpDir)
+
+ srcExists := filepath.Join(tmpDir, "src_exist.txt")
+ if err := ioutil.WriteFile(srcExists, []byte("fake data"), 0755); err != nil {
+ t.Fatalf("failed to create a src file %q for copying: %v", srcExists, err)
+ }
+
+ tests := []struct {
+ description string
+ src string
+ dst string
+ }{{
+ description: "src file does not exist",
+ src: "/src/not/exist",
+ dst: "/dst/not/exist",
+ }, {
+ description: "dst directory does not exist",
+ src: srcExists,
+ dst: "/dst/not/exist",
+ }}
+
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ if _, err := copyFile(tt.src, tt.dst); err == nil {
+ t.Errorf("got nil, expecting error")
+ }
+ })
+ }
+}
diff --git a/ui/metrics/upload_proto/upload.pb.go b/ui/metrics/upload_proto/upload.pb.go
index 1b1e5e8..614d4c7 100644
--- a/ui/metrics/upload_proto/upload.pb.go
+++ b/ui/metrics/upload_proto/upload.pb.go
@@ -30,7 +30,10 @@
// The target name.
TargetName *string `protobuf:"bytes,4,opt,name=target_name,json=targetName" json:"target_name,omitempty"`
// A list of metrics filepaths to upload.
- MetricsFiles []string `protobuf:"bytes,5,rep,name=metrics_files,json=metricsFiles" json:"metrics_files,omitempty"`
+ MetricsFiles []string `protobuf:"bytes,5,rep,name=metrics_files,json=metricsFiles" json:"metrics_files,omitempty"`
+ // A list of directories to delete after the copy of metrics files
+ // is completed for uploading.
+ DirectoriesToDelete []string `protobuf:"bytes,6,rep,name=directories_to_delete,json=directoriesToDelete" json:"directories_to_delete,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -96,6 +99,13 @@
return nil
}
+func (m *Upload) GetDirectoriesToDelete() []string {
+ if m != nil {
+ return m.DirectoriesToDelete
+ }
+ return nil
+}
+
func init() {
proto.RegisterType((*Upload)(nil), "soong_metrics_upload.Upload")
}
@@ -105,18 +115,20 @@
}
var fileDescriptor_91b94b655bd2a7e5 = []byte{
- // 201 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x2d, 0xc8, 0xc9,
- 0x4f, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x29, 0xce, 0xcf, 0xcf, 0x4b, 0x8f,
- 0xcf, 0x4d, 0x2d, 0x29, 0xca, 0x4c, 0x2e, 0x8e, 0x87, 0xc8, 0x29, 0xdd, 0x66, 0xe4, 0x62, 0x0b,
- 0x05, 0x33, 0x85, 0x8c, 0xb8, 0x44, 0x93, 0x8b, 0x52, 0x13, 0x4b, 0x32, 0xf3, 0xf3, 0xe2, 0x4b,
- 0x32, 0x73, 0x53, 0x8b, 0x4b, 0x12, 0x73, 0x0b, 0xe2, 0x73, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35,
- 0x58, 0x82, 0x84, 0x61, 0x92, 0x21, 0x30, 0x39, 0xdf, 0x62, 0x21, 0x33, 0x2e, 0xf1, 0xe4, 0xfc,
- 0xdc, 0x82, 0x9c, 0x54, 0x4c, 0x5d, 0x4c, 0x60, 0x5d, 0xa2, 0x08, 0x69, 0x64, 0x7d, 0xf2, 0x5c,
- 0xdc, 0x49, 0x45, 0x89, 0x79, 0xc9, 0x19, 0xf1, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0xcc, 0x0a, 0x8c,
- 0x1a, 0x9c, 0x41, 0x5c, 0x10, 0x21, 0xbf, 0xc4, 0xdc, 0x54, 0x90, 0x82, 0x92, 0xc4, 0xa2, 0xf4,
- 0xd4, 0x12, 0x88, 0x02, 0x16, 0x88, 0x02, 0x88, 0x10, 0x58, 0x81, 0x32, 0x17, 0x2f, 0xcc, 0x2b,
- 0x69, 0x99, 0x39, 0xa9, 0xc5, 0x12, 0xac, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x3c, 0x50, 0x41, 0x37,
- 0x90, 0x98, 0x93, 0x4c, 0x94, 0x14, 0x36, 0x5f, 0xc7, 0x83, 0x43, 0x04, 0x10, 0x00, 0x00, 0xff,
- 0xff, 0xe2, 0x01, 0x74, 0x65, 0x20, 0x01, 0x00, 0x00,
+ // 230 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4a, 0x04, 0x31,
+ 0x10, 0x86, 0xd9, 0xbb, 0xf3, 0xe0, 0xe2, 0xd9, 0xec, 0x79, 0x18, 0x44, 0x70, 0xd1, 0x66, 0x2b,
+ 0x0b, 0x0b, 0x1f, 0x40, 0xc4, 0x4e, 0x8b, 0xe5, 0x6c, 0x6c, 0x86, 0x98, 0x1d, 0xd7, 0x40, 0x92,
+ 0x09, 0xc9, 0xf8, 0x1c, 0xbe, 0xb2, 0x6c, 0xe2, 0xe2, 0x82, 0x76, 0xc3, 0xff, 0x7d, 0x7f, 0x31,
+ 0xbf, 0xd8, 0x7e, 0x06, 0x4b, 0xaa, 0xbf, 0x09, 0x91, 0x98, 0xea, 0xd3, 0x44, 0xe4, 0x07, 0x70,
+ 0xc8, 0xd1, 0xe8, 0x04, 0x85, 0x5d, 0x7d, 0x2d, 0xc4, 0xfa, 0x25, 0x9f, 0xf5, 0xad, 0xd8, 0xeb,
+ 0x88, 0x8a, 0x0d, 0x79, 0x60, 0xe3, 0x30, 0xb1, 0x72, 0x01, 0x5c, 0x92, 0x55, 0x53, 0xb5, 0xab,
+ 0x6e, 0x37, 0xc1, 0xc3, 0xc4, 0x9e, 0x52, 0x7d, 0x27, 0xce, 0x34, 0xb9, 0x60, 0xf1, 0x6f, 0x6b,
+ 0x91, 0x5b, 0xfb, 0x5f, 0x3c, 0xef, 0x5d, 0x8a, 0xe3, 0xb7, 0xa8, 0xbc, 0xfe, 0x00, 0xaf, 0x1c,
+ 0xca, 0x65, 0x53, 0xb5, 0x9b, 0x4e, 0x94, 0xe8, 0x59, 0x39, 0x1c, 0x05, 0x56, 0x71, 0x40, 0x2e,
+ 0xc2, 0xaa, 0x08, 0x25, 0xca, 0xc2, 0xb5, 0x38, 0x99, 0x5e, 0x79, 0x37, 0x16, 0x93, 0x3c, 0x6a,
+ 0x96, 0xed, 0xa6, 0xdb, 0xfe, 0x84, 0x8f, 0x63, 0x36, 0xbe, 0xd4, 0x9b, 0x88, 0x9a, 0x29, 0x1a,
+ 0x4c, 0xc0, 0x04, 0x3d, 0x5a, 0x64, 0x94, 0xeb, 0x2c, 0xef, 0x66, 0xf0, 0x40, 0x0f, 0x19, 0xdd,
+ 0x5f, 0xbc, 0x9e, 0xff, 0xb7, 0x14, 0xe4, 0x15, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x64, 0x04,
+ 0xa8, 0xf4, 0x54, 0x01, 0x00, 0x00,
}
diff --git a/ui/metrics/upload_proto/upload.proto b/ui/metrics/upload_proto/upload.proto
index 7a9f080..bcd0ab2 100644
--- a/ui/metrics/upload_proto/upload.proto
+++ b/ui/metrics/upload_proto/upload.proto
@@ -32,4 +32,8 @@
// A list of metrics filepaths to upload.
repeated string metrics_files = 5;
+
+ // A list of directories to delete after the copy of metrics files
+ // is completed for uploading.
+ repeated string directories_to_delete = 6;
}