Merge "Support including apk inside an apex"
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 3d1454e..aff706c 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -51,6 +51,7 @@
 	AddNeverAllowRules(createIncludeDirsRules()...)
 	AddNeverAllowRules(createTrebleRules()...)
 	AddNeverAllowRules(createLibcoreRules()...)
+	AddNeverAllowRules(createMediaRules()...)
 	AddNeverAllowRules(createJavaDeviceForHostRules()...)
 }
 
@@ -110,7 +111,7 @@
 
 		// TODO(b/67974785): always enforce the manifest
 		NeverAllow().
-			Without("name", "libhidltransport").
+			Without("name", "libhidltransport-impl-internal").
 			With("product_variables.enforce_vintf_manifest.cflags", "*").
 			Because("manifest enforcement should be independent of ."),
 
@@ -151,6 +152,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 4584585..b75b5b7 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -157,20 +157,6 @@
 			"manifest enforcement should be independent",
 		},
 	},
-	{
-		name: "libhidltransport enforce_vintf_manifest.cflags",
-		fs: map[string][]byte{
-			"Blueprints": []byte(`
-				cc_library {
-					name: "libhidltransport",
-					product_variables: {
-						enforce_vintf_manifest: {
-							cflags: ["-DSHOULD_NOT_EXIST"],
-						},
-					},
-				}`),
-		},
-	},
 
 	{
 		name: "no treble_linker_namespaces.cflags",
@@ -204,6 +190,19 @@
 		},
 	},
 	{
+		name: "dependency on updatable-media",
+		fs: map[string][]byte{
+			"Blueprints": []byte(`
+				java_library {
+					name: "needs_updatable_media",
+					libs: ["updatable-media"],
+				}`),
+		},
+		expectedErrors: []string{
+			"updatable-media includes private APIs. Use updatable_media_stubs instead.",
+		},
+	},
+	{
 		name: "java_device_for_host",
 		fs: map[string][]byte{
 			"Blueprints": []byte(`
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 48d070e..6f04672 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -367,10 +367,6 @@
 			sboxOutputs[i] = "__SBOX_OUT_DIR__/" + Rel(ctx, r.sboxOutDir.String(), output.String())
 		}
 
-		if depFile != nil {
-			sboxOutputs = append(sboxOutputs, "__SBOX_OUT_DIR__/"+Rel(ctx, r.sboxOutDir.String(), depFile.String()))
-		}
-
 		commandString = proptools.ShellEscape(commandString)
 		if !strings.HasPrefix(commandString, `'`) {
 			commandString = `'` + commandString + `'`
@@ -380,8 +376,13 @@
 		sboxCmd.BuiltTool(ctx, "sbox").
 			Flag("-c").Text(commandString).
 			Flag("--sandbox-path").Text(shared.TempDirForOutDir(PathForOutput(ctx).String())).
-			Flag("--output-root").Text(r.sboxOutDir.String()).
-			Flags(sboxOutputs)
+			Flag("--output-root").Text(r.sboxOutDir.String())
+
+		if depFile != nil {
+			sboxCmd.Flag("--depfile-out").Text(depFile.String())
+		}
+
+		sboxCmd.Flags(sboxOutputs)
 
 		commandString = sboxCmd.buf.String()
 		tools = append(tools, sboxCmd.tools...)
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 6eba4f1..b484811 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -475,6 +475,7 @@
 	FailIfErrored(t, errs)
 
 	check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraCmdDeps []string) {
+		t.Helper()
 		if params.RuleParams.Command != wantCommand {
 			t.Errorf("\nwant RuleParams.Command = %q\n                      got %q", wantCommand, params.RuleParams.Command)
 		}
@@ -518,13 +519,14 @@
 	t.Run("sbox", func(t *testing.T) {
 		outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox")
 		outFile := filepath.Join(outDir, "foo_sbox")
+		depFile := filepath.Join(outDir, "foo_sbox.d")
 		sbox := filepath.Join(buildDir, "host", config.PrebuiltOS(), "bin/sbox")
 		sandboxPath := shared.TempDirForOutDir(buildDir)
 
-		cmd := sbox + ` -c 'cp bar __SBOX_OUT_DIR__/foo_sbox' --sandbox-path ` + sandboxPath + " --output-root " + outDir + " __SBOX_OUT_DIR__/foo_sbox __SBOX_OUT_DIR__/foo_sbox.d"
+		cmd := sbox + ` -c 'cp bar __SBOX_OUT_DIR__/foo_sbox' --sandbox-path ` + sandboxPath + " --output-root " + outDir + " --depfile-out " + depFile + " __SBOX_OUT_DIR__/foo_sbox"
 
 		check(t, ctx.ModuleForTests("foo_sbox", "").Rule("rule"),
-			cmd, outFile, outFile+".d", false, []string{sbox})
+			cmd, outFile, depFile, false, []string{sbox})
 	})
 	t.Run("singleton", func(t *testing.T) {
 		outFile := filepath.Join(buildDir, "baz")
diff --git a/apex/apex.go b/apex/apex.go
index 13e9cb9..1e99ff8 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1217,7 +1217,7 @@
 		implicitInputs = append(implicitInputs, imageContentFile)
 		whitelistedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Whitelisted_files))
 
-		phonyOutput := android.PathForPhony(ctx, ctx.ModuleName()+"-diff-phony-output")
+		phonyOutput := android.PathForModuleOut(ctx, ctx.ModuleName()+"-diff-phony-output")
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        diffApexContentRule,
 			Implicits:   implicitInputs,
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 4908cb7..1f169e4 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",
@@ -169,11 +168,6 @@
 		"-Wno-tautological-constant-compare",
 		"-Wno-tautological-type-limit-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",
@@ -182,9 +176,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 72c0ecb..415518c 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -56,7 +56,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/dep_fixer/Android.bp b/cmd/dep_fixer/Android.bp
index d2d1113..97364d5 100644
--- a/cmd/dep_fixer/Android.bp
+++ b/cmd/dep_fixer/Android.bp
@@ -14,10 +14,6 @@
 
 blueprint_go_binary {
     name: "dep_fixer",
-    deps: ["androidmk-parser"],
-    srcs: [
-        "main.go",
-        "deps.go",
-    ],
-    testSrcs: ["deps_test.go"],
+    deps: ["soong-makedeps"],
+    srcs: ["main.go"],
 }
diff --git a/cmd/dep_fixer/main.go b/cmd/dep_fixer/main.go
index f94cf2f..d1bd139 100644
--- a/cmd/dep_fixer/main.go
+++ b/cmd/dep_fixer/main.go
@@ -25,6 +25,8 @@
 	"io/ioutil"
 	"log"
 	"os"
+
+	"android/soong/makedeps"
 )
 
 func main() {
@@ -39,7 +41,7 @@
 		log.Fatal("Expected at least one input file as an argument")
 	}
 
-	var mergedDeps *Deps
+	var mergedDeps *makedeps.Deps
 	var firstInput []byte
 
 	for i, arg := range flag.Args() {
@@ -48,7 +50,7 @@
 			log.Fatalf("Error opening %q: %v", arg, err)
 		}
 
-		deps, err := Parse(arg, bytes.NewBuffer(append([]byte(nil), input...)))
+		deps, err := makedeps.Parse(arg, bytes.NewBuffer(append([]byte(nil), input...)))
 		if err != nil {
 			log.Fatalf("Failed to parse: %v", err)
 		}
diff --git a/cmd/sbox/Android.bp b/cmd/sbox/Android.bp
index fe4c7bb..a706810d 100644
--- a/cmd/sbox/Android.bp
+++ b/cmd/sbox/Android.bp
@@ -14,6 +14,7 @@
 
 blueprint_go_binary {
     name: "sbox",
+    deps: ["soong-makedeps"],
     srcs: [
         "sbox.go",
     ],
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 4ac9295..7057b33 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -15,6 +15,7 @@
 package main
 
 import (
+	"bytes"
 	"errors"
 	"flag"
 	"fmt"
@@ -25,6 +26,8 @@
 	"path/filepath"
 	"strings"
 	"time"
+
+	"android/soong/makedeps"
 )
 
 var (
@@ -152,9 +155,6 @@
 			return err
 		}
 		allOutputs = append(allOutputs, sandboxedDepfile)
-		if !strings.Contains(rawCommand, "__SBOX_DEPFILE__") {
-			return fmt.Errorf("the --depfile-out argument only makes sense if the command contains the text __SBOX_DEPFILE__")
-		}
 		rawCommand = strings.Replace(rawCommand, "__SBOX_DEPFILE__", filepath.Join(tempDir, sandboxedDepfile), -1)
 
 	}
@@ -281,6 +281,26 @@
 		}
 	}
 
+	// Rewrite the depfile so that it doesn't include the (randomized) sandbox directory
+	if depfileOut != "" {
+		in, err := ioutil.ReadFile(depfileOut)
+		if err != nil {
+			return err
+		}
+
+		deps, err := makedeps.Parse(depfileOut, bytes.NewBuffer(in))
+		if err != nil {
+			return err
+		}
+
+		deps.Output = "outputfile"
+
+		err = ioutil.WriteFile(depfileOut, deps.Print(), 0666)
+		if err != nil {
+			return err
+		}
+	}
+
 	// TODO(jeffrygaston) if a process creates more output files than it declares, should there be a warning?
 	return nil
 }
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 39303bf..ec4f90e 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -180,6 +180,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)
@@ -187,6 +192,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 b371cbf..6be83c3 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"
 
@@ -45,6 +45,7 @@
 		"core-icu4j",
 		"core-oj",
 		"core-libart",
+		"updatable-media",
 	}
 )
 
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 63da6d2..9eaa1b6 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -294,8 +294,10 @@
 	android.InitDefaultableModule(module)
 }
 
-func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
-	if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
+func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
+	if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
+		return false
+	} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
 		return true
 	} else if String(apiToCheck.Api_file) != "" {
 		panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
@@ -765,8 +767,8 @@
 }
 
 func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Api_filename) != "" {
 
 		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
@@ -774,8 +776,8 @@
 		d.apiFilePath = d.apiFile
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Removed_api_filename) != "" {
 		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
 		cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
@@ -993,7 +995,7 @@
 
 	rule.Build(pctx, ctx, "javadoc", desc)
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
 		!ctx.Config().IsPdkBuild() {
 
 		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
@@ -1062,7 +1064,7 @@
 		rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
 		!ctx.Config().IsPdkBuild() {
 
 		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
@@ -1192,16 +1194,16 @@
 }
 
 func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Api_filename) != "" {
 		d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
 		cmd.FlagWithOutput("--api ", d.apiFile)
 		d.apiFilePath = d.apiFile
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
+		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
 		String(d.properties.Removed_api_filename) != "" {
 		d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
 		cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
@@ -1458,7 +1460,7 @@
 
 	// Create rule for apicheck
 
-	if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
 		!ctx.Config().IsPdkBuild() {
 
 		if len(d.Javadoc.properties.Out) > 0 {
@@ -1543,7 +1545,7 @@
 		rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
 	}
 
-	if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
+	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
 		!ctx.Config().IsPdkBuild() {
 
 		if len(d.Javadoc.properties.Out) > 0 {
diff --git a/java/java_test.go b/java/java_test.go
index c55e325..a932319 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1108,7 +1108,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 1de56a5..cbe3557 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -34,10 +34,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
@@ -54,6 +61,8 @@
 
 	libs  []string
 	tests []string
+
+	roboSrcJar android.Path
 }
 
 func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -66,11 +75,35 @@
 	}
 
 	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))
 	}
@@ -109,6 +142,41 @@
 	return ret
 }
 
+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()
 
@@ -144,6 +212,7 @@
 	fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", module)
 	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())
 	fmt.Fprintln(w, "LOCAL_ROBOTEST_FILES :=", strings.Join(tests, " "))
 	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 5d116a7..a37c0a9 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",
diff --git a/makedeps/Android.bp b/makedeps/Android.bp
new file mode 100644
index 0000000..b77b08f
--- /dev/null
+++ b/makedeps/Android.bp
@@ -0,0 +1,21 @@
+// Copyright 2019 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.
+
+bootstrap_go_package {
+    name: "soong-makedeps",
+    pkgPath: "android/soong/makedeps",
+    deps: ["androidmk-parser"],
+    srcs: ["deps.go"],
+    testSrcs: ["deps_test.go"],
+}
diff --git a/cmd/dep_fixer/deps.go b/makedeps/deps.go
similarity index 98%
rename from cmd/dep_fixer/deps.go
rename to makedeps/deps.go
index 64c97f5..e64e6f7 100644
--- a/cmd/dep_fixer/deps.go
+++ b/makedeps/deps.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package makedeps
 
 import (
 	"bytes"
diff --git a/cmd/dep_fixer/deps_test.go b/makedeps/deps_test.go
similarity index 99%
rename from cmd/dep_fixer/deps_test.go
rename to makedeps/deps_test.go
index 0a779b7..a32df65 100644
--- a/cmd/dep_fixer/deps_test.go
+++ b/makedeps/deps_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package makedeps
 
 import (
 	"bytes"
diff --git a/rust/rust_test.go b/rust/rust_test.go
index c68cfe7..f7c96dd 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -17,6 +17,7 @@
 import (
 	"io/ioutil"
 	"os"
+	"runtime"
 	"testing"
 
 	"android/soong/android"
@@ -50,6 +51,11 @@
 }
 
 func testRust(t *testing.T, bp string) *android.TestContext {
+	// TODO (b/140435149)
+	if runtime.GOOS != "linux" {
+		t.Skip("Only the Linux toolchain is supported for Rust")
+	}
+
 	t.Helper()
 	config := android.TestArchConfig(buildDir, nil)
 
@@ -66,6 +72,11 @@
 }
 
 func testRustError(t *testing.T, pattern string, bp string) {
+	// TODO (b/140435149)
+	if runtime.GOOS != "linux" {
+		t.Skip("Only the Linux toolchain is supported for Rust")
+	}
+
 	t.Helper()
 	config := android.TestArchConfig(buildDir, nil)
 
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 738ef40..b97391b 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -120,7 +120,6 @@
 
 	// These are currently Linux-only toybox tools (but can be switched now).
 	"date": LinuxOnlyPrebuilt,
-	"stat": LinuxOnlyPrebuilt,
 
 	// These are toybox tools that only work on Linux.
 	"pgrep": LinuxOnlyPrebuilt,