Merge "Allow java_test.go tests to use any Android.bp file" am: 45656aacab
am: e6cb60da57

Change-Id: I0fedcef906e6e59e004115d421df1a152348a02c
diff --git a/android/api_levels.go b/android/api_levels.go
index 961685a..4f6efee 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -71,6 +71,7 @@
 			"O":     26,
 			"O-MR1": 27,
 			"P":     28,
+			"Q":     29,
 		}
 		for i, codename := range config.PlatformVersionCombinedCodenames() {
 			apiLevelsMap[codename] = baseApiLevel + i
diff --git a/android/neverallow.go b/android/neverallow.go
index ee3bf4a..9cfa0eb 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -51,6 +51,7 @@
 	rules := []*rule{}
 	rules = append(rules, createTrebleRules()...)
 	rules = append(rules, createLibcoreRules()...)
+	rules = append(rules, createMediaRules()...)
 	rules = append(rules, createJavaDeviceForHostRules()...)
 	return rules
 }
@@ -112,6 +113,14 @@
 	return rules
 }
 
+func createMediaRules() []*rule {
+	return []*rule{
+		neverallow().
+			with("libs", "updatable-media").
+			because("updatable-media includes private APIs. Use updatable_media_stubs instead."),
+	}
+}
+
 func createJavaDeviceForHostRules() []*rule {
 	javaDeviceForHostProjectsWhitelist := []string{
 		"external/guava",
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 40ccf14..53436c2 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -136,6 +136,17 @@
 		expectedError: "",
 	},
 	{
+		name: "dependency on updatable-media",
+		fs: map[string][]byte{
+			"Blueprints": []byte(`
+				java_library {
+					name: "needs_updatable_media",
+					libs: ["updatable-media"],
+				}`),
+		},
+		expectedError: "updatable-media includes private APIs. Use updatable_media_stubs instead.",
+	},
+	{
 		name: "java_device_for_host",
 		fs: map[string][]byte{
 			"Blueprints": []byte(`
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 47b60e7..59c78a6 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -101,9 +101,8 @@
 		// not emit the table by default on Android since NDK still uses GNU binutils.
 		"-faddrsig",
 
-		// Make implicit fallthrough an error in the future.
+		// -Wimplicit-fallthrough is not enabled by -Wall.
 		"-Wimplicit-fallthrough",
-		"-Wno-error=implicit-fallthrough",
 
 		// Help catch common 32/64-bit errors.
 		"-Werror=int-conversion",
@@ -171,11 +170,6 @@
 		"-Wno-tautological-unsigned-enum-zero-compare",
 		"-Wno-tautological-unsigned-zero-compare",
 
-		// http://b/72330874 Disable -Wenum-compare until the instances detected by this new
-		// warning are fixed.
-		"-Wno-enum-compare",
-		"-Wno-enum-compare-switch",
-
 		// Disable c++98-specific warning since Android is not concerned with C++98
 		// compatibility.
 		"-Wno-c++98-compat-extra-semi",
@@ -184,9 +178,11 @@
 		"-Wno-return-std-move-in-c++11",
 	}, " "))
 
-	// Extra cflags for projects under external/ directory
+	// Extra cflags for projects under external/ directory to disable warnings that are infeasible
+	// to fix in all the external projects and their upstream repos.
 	pctx.StaticVariable("ClangExtraExternalCflags", strings.Join([]string{
-		// TODO(yikong): Move -Wno flags here
+		"-Wno-enum-compare",
+		"-Wno-enum-compare-switch",
 
 		// http://b/72331524 Allow null pointer arithmetic until the instances detected by
 		// this new warning are fixed.
diff --git a/cc/sanitize.go b/cc/sanitize.go
index fdda7be..6859f39 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -57,7 +57,8 @@
 
 	minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
 		"-fno-sanitize-recover=integer,undefined"}
-	hwasanGlobalOptions = []string{"heap_history_size=1023,stack_history_size=512"}
+	hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
+		"export_memory_stats=0", "max_malloc_fill_size=0"}
 )
 
 type sanitizerType int
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 5f9bd01..4500eb1 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -175,6 +175,11 @@
 		}
 	}
 
+	// Fix up the source tree due to a repo bug where it doesn't remove
+	// linkfiles that have been removed
+	fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.bp")
+	fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.mk")
+
 	f := build.NewSourceFinder(buildCtx, config)
 	defer f.Shutdown()
 	build.FindSources(buildCtx, config, f)
@@ -182,6 +187,20 @@
 	c.run(buildCtx, config, args, logsDir)
 }
 
+func fixBadDanglingLink(ctx build.Context, name string) {
+	_, err := os.Lstat(name)
+	if err != nil {
+		return
+	}
+	_, err = os.Stat(name)
+	if os.IsNotExist(err) {
+		err = os.Remove(name)
+		if err != nil {
+			ctx.Fatalf("Failed to remove dangling link %q: %v", name, err)
+		}
+	}
+}
+
 func dumpVar(ctx build.Context, config build.Config, args []string, _ string) {
 	flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
 	flags.Usage = func() {
diff --git a/java/config/config.go b/java/config/config.go
index 6ade649..b72e89d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -29,7 +29,7 @@
 
 	DefaultBootclasspathLibraries = []string{"core.platform.api.stubs", "core-lambda-stubs"}
 	DefaultSystemModules          = "core-platform-api-stubs-system-modules"
-	DefaultLibraries              = []string{"ext", "framework"}
+	DefaultLibraries              = []string{"ext", "framework", "updatable_media_stubs"}
 	DefaultLambdaStubsLibrary     = "core-lambda-stubs"
 	SdkLambdaStubsPath            = "prebuilts/sdk/tools/core-lambda-stubs.jar"
 
@@ -44,6 +44,7 @@
 		"conscrypt",
 		"core-oj",
 		"core-libart",
+		"updatable-media",
 	}
 )
 
diff --git a/java/java_test.go b/java/java_test.go
index 4c8367b..f04bbe4 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1030,7 +1030,7 @@
 		checkPatchModuleFlag(t, ctx, "foo", "")
 		expected := "java.base=.:" + buildDir
 		checkPatchModuleFlag(t, ctx, "bar", expected)
-		expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework")}, ":")
+		expected = "java.base=" + strings.Join([]string{".", buildDir, moduleToPath("ext"), moduleToPath("framework"), moduleToPath("updatable_media_stubs")}, ":")
 		checkPatchModuleFlag(t, ctx, "baz", expected)
 	})
 }
diff --git a/java/robolectric.go b/java/robolectric.go
index b87ee0d..19c4b94 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -33,10 +33,17 @@
 	"truth-prebuilt",
 }
 
+var (
+	roboCoverageLibsTag = dependencyTag{name: "roboSrcs"}
+)
+
 type robolectricProperties struct {
 	// The name of the android_app module that the tests will run against.
 	Instrumentation_for *string
 
+	// Additional libraries for which coverage data should be generated
+	Coverage_libs []string
+
 	Test_options struct {
 		// Timeout in seconds when running the tests.
 		Timeout *int64
@@ -49,6 +56,8 @@
 	robolectricProperties robolectricProperties
 
 	libs []string
+
+	roboSrcJar android.Path
 }
 
 func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -61,16 +70,75 @@
 	}
 
 	ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
+
+	ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
 }
 
 func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
+		Join(ctx, "com/android/tools/test_config.properties")
+
+	// TODO: this inserts paths to built files into the test, it should really be inserting the contents.
+	instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag)
+
+	if len(instrumented) != 1 {
+		panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented)))
+	}
+
+	instrumentedApp, ok := instrumented[0].(*AndroidApp)
+	if !ok {
+		ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
+	}
+
+	generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp)
+	r.extraResources = android.Paths{roboTestConfig}
+
 	r.Library.GenerateAndroidBuildActions(ctx)
 
+	roboSrcJar := android.PathForModuleGen(ctx, "robolectric", ctx.ModuleName()+".srcjar")
+	r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp)
+	r.roboSrcJar = roboSrcJar
+
 	for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
 		r.libs = append(r.libs, ctx.OtherModuleName(dep))
 	}
 }
 
+func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath, instrumentedApp *AndroidApp) {
+	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("&&").
+		Textf(`echo "android_resource_apk=%s" >>`, resourceApk.String()).Output(outputFile).
+		// Make it depend on the files to which it points so the test file's timestamp is updated whenever the
+		// contents change
+		Implicit(manifest).
+		Implicit(resourceApk)
+
+	rule.Build(pctx, ctx, "generate_test_config", "generate test_config.properties")
+}
+
+func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath,
+	instrumentedApp *AndroidApp) {
+
+	srcJarArgs := copyOf(instrumentedApp.srcJarArgs)
+	srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...)
+
+	for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) {
+		if dep, ok := m.(Dependency); ok {
+			depSrcJarArgs, depSrcJarDeps := dep.SrcJarArgs()
+			srcJarArgs = append(srcJarArgs, depSrcJarArgs...)
+			srcJarDeps = append(srcJarDeps, depSrcJarDeps...)
+		}
+	}
+
+	TransformResourcesToJar(ctx, outputFile, srcJarArgs, srcJarDeps)
+}
+
 func (r *robolectricTest) AndroidMk() android.AndroidMkData {
 	data := r.Library.AndroidMk()
 
@@ -83,6 +151,7 @@
 		fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", name)
 		fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
 		fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
+		fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String())
 		if t := r.robolectricProperties.Test_options.Timeout; t != nil {
 			fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
 		}
diff --git a/java/testing.go b/java/testing.go
index a9d4670..4ab56c8 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -38,6 +38,7 @@
 	extraModules := []string{
 		"core-lambda-stubs",
 		"ext",
+		"updatable_media_stubs",
 		"android_stubs_current",
 		"android_system_stubs_current",
 		"android_test_stubs_current",