Merge changes from topic "mingw-clang"

* changes:
  Use clang for windows host modules
  Use -static-libgcc for Windows
diff --git a/android/config.go b/android/config.go
index f5a5e8e..8330b3d 100644
--- a/android/config.go
+++ b/android/config.go
@@ -108,8 +108,7 @@
 	captureBuild      bool // true for tests, saves build parameters for each module
 	ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
 
-	useOpenJDK9    bool // Use OpenJDK9, but possibly target 1.8
-	targetOpenJDK9 bool // Use OpenJDK9 and target 1.9
+	targetOpenJDK9 bool // Target 1.9
 
 	stopBefore bootstrap.StopBefore
 
@@ -321,22 +320,13 @@
 
 func (c *config) fromEnv() error {
 	switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
-	case "":
-		if c.Getenv("RUN_ERROR_PRONE") != "true" {
-			// Use OpenJDK9, but target 1.8
-			c.useOpenJDK9 = true
-		}
-	case "false":
-		// Use OpenJDK8
-	case "1.8":
-		// Use OpenJDK9, but target 1.8
-		c.useOpenJDK9 = true
+	case "", "1.8":
+		// Nothing, we always use OpenJDK9
 	case "true":
 		// Use OpenJDK9 and target 1.9
-		c.useOpenJDK9 = true
 		c.targetOpenJDK9 = true
 	default:
-		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "false", "1.8", or "true"`)
+		return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "1.8", or "true"`)
 	}
 
 	return nil
@@ -631,9 +621,8 @@
 	return Bool(c.productVariables.UseGoma)
 }
 
-// Returns true if OpenJDK9 prebuilts are being used
-func (c *config) UseOpenJDK9() bool {
-	return c.useOpenJDK9
+func (c *config) RunErrorProne() bool {
+	return c.IsEnvTrue("RUN_ERROR_PRONE")
 }
 
 // Returns true if -source 1.9 -target 1.9 is being passed to javac
diff --git a/android/defaults.go b/android/defaults.go
index c704529..d4fbf48 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -131,11 +131,16 @@
 func defaultsMutator(ctx TopDownMutatorContext) {
 	if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
 		var defaultsList []Defaults
+		seen := make(map[Defaults]bool)
+
 		ctx.WalkDeps(func(module, parent Module) bool {
 			if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
 				if defaults, ok := module.(Defaults); ok {
-					defaultsList = append(defaultsList, defaults)
-					return len(defaults.defaults().Defaults) > 0
+					if !seen[defaults] {
+						seen[defaults] = true
+						defaultsList = append(defaultsList, defaults)
+						return len(defaults.defaults().Defaults) > 0
+					}
 				} else {
 					ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
 						ctx.OtherModuleName(module))
diff --git a/android/module.go b/android/module.go
index 3316a44..b6220dc 100644
--- a/android/module.go
+++ b/android/module.go
@@ -144,7 +144,9 @@
 	VisitDirectDeps(visit func(Module))
 	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
 	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
+	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirst(visit func(Module))
+	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
 	WalkDeps(visit func(Module, Module) bool)
 
@@ -539,6 +541,7 @@
 	ctx blueprint.ModuleContext) Paths {
 
 	result := Paths{}
+	// TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
 	ctx.VisitDepsDepthFirstIf(isFileInstaller,
 		func(m blueprint.Module) {
 			fileInstaller := m.(fileInstaller)
diff --git a/android/singleton.go b/android/singleton.go
index f577b0a..fa1efdc 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -50,7 +50,9 @@
 
 	VisitAllModules(visit func(Module))
 	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
+	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirst(module Module, visit func(Module))
+	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
 	VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
 		visit func(Module))
 
diff --git a/cc/cc.go b/cc/cc.go
index b7183d7..592f373 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -52,7 +52,7 @@
 		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
 		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
 
-		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator())
+		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
 
 		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
 		ctx.TopDown("vndk_deps", sabiDepsMutator)
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index a20d556..5d53a8c 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -19,6 +19,13 @@
 	"strings"
 )
 
+// clang-tidy doesn't recognize every flag that clang does. This is unlikely to
+// be a complete list, but we can populate this with the ones we know to avoid
+// issues with clang-diagnostic-unused-command-line-argument.
+var ClangTidyUnknownCflags = sorted([]string{
+	"-Wa,%",
+})
+
 func init() {
 	// Most Android source files are not clang-tidy clean yet.
 	// Global tidy checks include only google*, performance*,
diff --git a/cc/makevars.go b/cc/makevars.go
index 5a912e1..88d4639 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -75,6 +75,7 @@
 	ctx.Strict("LLVM_OBJCOPY", "${config.ClangBin}/llvm-objcopy")
 	ctx.Strict("LLVM_STRIP", "${config.ClangBin}/llvm-strip")
 	ctx.Strict("PATH_TO_CLANG_TIDY", "${config.ClangBin}/clang-tidy")
+	ctx.Strict("CLANG_TIDY_UNKNOWN_CFLAGS", strings.Join(config.ClangTidyUnknownCflags, " "))
 	ctx.StrictSorted("CLANG_CONFIG_UNKNOWN_CFLAGS", strings.Join(config.ClangUnknownCflags, " "))
 
 	ctx.Strict("RS_LLVM_PREBUILTS_VERSION", "${config.RSClangVersion}")
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 38f4fc2..080ac09 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -21,6 +21,8 @@
 	"strings"
 	"sync"
 
+	"github.com/google/blueprint"
+
 	"android/soong/android"
 	"android/soong/cc/config"
 )
@@ -610,43 +612,54 @@
 	return sanitizerVal != nil && *sanitizerVal == true
 }
 
+func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
+	t, ok := tag.(dependencyTag)
+	return ok && t.library || t == reuseObjTag
+}
+
 // Propagate asan requirements down from binaries
 func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
 	return func(mctx android.TopDownMutatorContext) {
 		if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
-			mctx.VisitDepsDepthFirst(func(module android.Module) {
-				if d, ok := module.(*Module); ok && d.sanitize != nil &&
+			mctx.WalkDeps(func(child, parent android.Module) bool {
+				if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
+					return false
+				}
+				if d, ok := child.(*Module); ok && d.sanitize != nil &&
 					!Bool(d.sanitize.Properties.Sanitize.Never) &&
 					!d.sanitize.isSanitizerExplicitlyDisabled(t) {
 					if (t == cfi && d.static()) || t != cfi {
 						d.sanitize.Properties.SanitizeDep = true
 					}
 				}
+				return true
 			})
 		}
 	}
 }
 
 // Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
-func sanitizerRuntimeDepsMutator() func(android.TopDownMutatorContext) {
-	return func(mctx android.TopDownMutatorContext) {
-		if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
-			mctx.VisitDepsDepthFirst(func(module android.Module) {
-				if d, ok := module.(*Module); ok && d.static() && d.sanitize != nil {
+func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
+	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
+		mctx.WalkDeps(func(child, parent android.Module) bool {
+			if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
+				return false
+			}
+			if d, ok := child.(*Module); ok && d.static() && d.sanitize != nil {
 
-					if enableMinimalRuntime(d.sanitize) {
-						// If a static dependency is built with the minimal runtime,
-						// make sure we include the ubsan minimal runtime.
-						c.sanitize.Properties.MinimalRuntimeDep = true
-					} else if Bool(d.sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
-						len(d.sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0 {
-						// If a static dependency runs with full ubsan diagnostics,
-						// make sure we include the ubsan runtime.
-						c.sanitize.Properties.UbsanRuntimeDep = true
-					}
+				if enableMinimalRuntime(d.sanitize) {
+					// If a static dependency is built with the minimal runtime,
+					// make sure we include the ubsan minimal runtime.
+					c.sanitize.Properties.MinimalRuntimeDep = true
+				} else if Bool(d.sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
+					len(d.sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0 {
+					// If a static dependency runs with full ubsan diagnostics,
+					// make sure we include the ubsan runtime.
+					c.sanitize.Properties.UbsanRuntimeDep = true
 				}
-			})
-		}
+			}
+			return true
+		})
 	}
 }
 
diff --git a/java/aar.go b/java/aar.go
index 415170e..da353e0 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -475,6 +475,10 @@
 	return nil
 }
 
+func (a *AARImport) ExportedSdkLibs() []string {
+	return nil
+}
+
 var _ android.PrebuiltInterface = (*Import)(nil)
 
 func AARImportFactory() android.Module {
diff --git a/java/androidmk.go b/java/androidmk.go
index ab9ceeb..d6095ae 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -63,6 +63,10 @@
 					fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", library.jacocoReportClassesFile.String())
 				}
 
+				if len(library.exportedSdkLibs) != 0 {
+					fmt.Fprintln(w, "LOCAL_EXPORT_SDK_LIBRARIES :=", strings.Join(library.exportedSdkLibs, " "))
+				}
+
 				// Temporary hack: export sources used to compile framework.jar to Make
 				// to be used for droiddoc
 				// TODO(ccross): remove this once droiddoc is in soong
diff --git a/java/builder.go b/java/builder.go
index d338623..1944e69 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -26,7 +26,6 @@
 	"github.com/google/blueprint"
 
 	"android/soong/android"
-	"android/soong/java/config"
 )
 
 var (
@@ -43,7 +42,7 @@
 			Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
 				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
 				`${config.SoongJavacWrapper} ${config.JavacWrapper}${config.JavacCmd} ${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
-				`$javacFlags $bootClasspath $classpath ` +
+				`$processorpath $javacFlags $bootClasspath $classpath ` +
 				`-source $javaVersion -target $javaVersion ` +
 				`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list && ` +
 				`${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
@@ -56,7 +55,7 @@
 			Rspfile:          "$out.rsp",
 			RspfileContent:   "$in",
 		},
-		"javacFlags", "bootClasspath", "classpath", "srcJars", "srcJarDir",
+		"javacFlags", "bootClasspath", "classpath", "processorpath", "srcJars", "srcJarDir",
 		"outDir", "annoDir", "javaVersion")
 
 	kotlinc = pctx.AndroidGomaStaticRule("kotlinc",
@@ -80,29 +79,6 @@
 		},
 		"kotlincFlags", "classpath", "srcJars", "srcJarDir", "outDir", "kotlinJvmTarget")
 
-	errorprone = pctx.AndroidStaticRule("errorprone",
-		blueprint.RuleParams{
-			Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
-				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
-				`${config.SoongJavacWrapper} ${config.ErrorProneCmd} ` +
-				`$javacFlags $bootClasspath $classpath ` +
-				`-source $javaVersion -target $javaVersion ` +
-				`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list && ` +
-				`${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
-			CommandDeps: []string{
-				"${config.JavaCmd}",
-				"${config.ErrorProneJavacJar}",
-				"${config.ErrorProneJar}",
-				"${config.SoongZipCmd}",
-				"${config.ZipSyncCmd}",
-			},
-			CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
-			Rspfile:          "$out.rsp",
-			RspfileContent:   "$in",
-		},
-		"javacFlags", "bootClasspath", "classpath", "srcJars", "srcJarDir",
-		"outDir", "annoDir", "javaVersion")
-
 	turbine = pctx.AndroidStaticRule("turbine",
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -155,11 +131,13 @@
 	javacFlags    string
 	bootClasspath classpath
 	classpath     classpath
+	processorPath classpath
 	systemModules classpath
 	aidlFlags     string
 	javaVersion   string
 
 	errorProneExtraJavacFlags string
+	errorProneProcessorPath   classpath
 
 	kotlincFlags     string
 	kotlincClasspath classpath
@@ -207,26 +185,24 @@
 		desc += strconv.Itoa(shardIdx)
 	}
 
-	transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc, javac)
+	transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc)
 }
 
 func RunErrorProne(ctx android.ModuleContext, outputFile android.WritablePath,
 	srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
 
-	if config.ErrorProneJar == "" {
-		ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
-	}
+	flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
 
 	if len(flags.errorProneExtraJavacFlags) > 0 {
 		if len(flags.javacFlags) > 0 {
-			flags.javacFlags = flags.errorProneExtraJavacFlags + " " + flags.javacFlags
+			flags.javacFlags += " " + flags.errorProneExtraJavacFlags
 		} else {
 			flags.javacFlags = flags.errorProneExtraJavacFlags
 		}
 	}
 
 	transformJavaToClasses(ctx, outputFile, -1, srcFiles, srcJars, flags, nil,
-		"errorprone", "errorprone", errorprone)
+		"errorprone", "errorprone")
 }
 
 func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android.WritablePath,
@@ -275,7 +251,7 @@
 func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
 	shardIdx int, srcFiles, srcJars android.Paths,
 	flags javaBuilderFlags, deps android.Paths,
-	intermediatesDir, desc string, rule blueprint.Rule) {
+	intermediatesDir, desc string) {
 
 	deps = append(deps, srcJars...)
 
@@ -295,6 +271,7 @@
 	}
 
 	deps = append(deps, flags.classpath...)
+	deps = append(deps, flags.processorPath...)
 
 	srcJarDir := "srcjars"
 	outDir := "classes"
@@ -306,7 +283,7 @@
 		annoDir = filepath.Join(shardDir, annoDir)
 	}
 	ctx.Build(pctx, android.BuildParams{
-		Rule:        rule,
+		Rule:        javac,
 		Description: desc,
 		Output:      outputFile,
 		Inputs:      srcFiles,
@@ -315,6 +292,7 @@
 			"javacFlags":    flags.javacFlags,
 			"bootClasspath": bootClasspath,
 			"classpath":     flags.classpath.FormJavaClassPath("-classpath"),
+			"processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
 			"srcJars":       strings.Join(srcJars.Strings(), " "),
 			"srcJarDir":     android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
 			"outDir":        android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
diff --git a/java/config/error_prone.go b/java/config/error_prone.go
index 2c1c002..48681b5 100644
--- a/java/config/error_prone.go
+++ b/java/config/error_prone.go
@@ -14,39 +14,40 @@
 
 package config
 
-import "android/soong/android"
+import (
+	"strings"
+
+	"android/soong/android"
+)
 
 var (
 	// These will be filled out by external/error_prone/soong/error_prone.go if it is available
-	ErrorProneJavacJar              string
-	ErrorProneJar                   string
-	ErrorProneClasspath             string
-	ErrorProneChecksError           string
-	ErrorProneChecksWarning         string
-	ErrorProneChecksDefaultDisabled string
-	ErrorProneFlags                 string
+	ErrorProneClasspath             []string
+	ErrorProneChecksError           []string
+	ErrorProneChecksWarning         []string
+	ErrorProneChecksDefaultDisabled []string
+	ErrorProneChecksOff             []string
+	ErrorProneFlags                 []string
 )
 
 // Wrapper that grabs value of val late so it can be initialized by a later module's init function
-func errorProneVar(name string, val *string) {
+func errorProneVar(name string, val *[]string, sep string) {
 	pctx.VariableFunc(name, func(android.PackageVarContext) string {
-		return *val
+		return strings.Join(*val, sep)
 	})
 }
 
 func init() {
-	errorProneVar("ErrorProneJar", &ErrorProneJar)
-	errorProneVar("ErrorProneJavacJar", &ErrorProneJavacJar)
-	errorProneVar("ErrorProneClasspath", &ErrorProneClasspath)
-	errorProneVar("ErrorProneChecksError", &ErrorProneChecksError)
-	errorProneVar("ErrorProneChecksWarning", &ErrorProneChecksWarning)
-	errorProneVar("ErrorProneChecksDefaultDisabled", &ErrorProneChecksDefaultDisabled)
-	errorProneVar("ErrorProneFlags", &ErrorProneFlags)
-
-	pctx.StaticVariable("ErrorProneCmd",
-		"${JavaCmd} -Xmx${JavacHeapSize} -Xbootclasspath/p:${ErrorProneJavacJar} "+
-			"-cp ${ErrorProneJar}:${ErrorProneClasspath} "+
-			"${ErrorProneFlags} ${CommonJdkFlags} "+
-			"${ErrorProneChecksError} ${ErrorProneChecksWarning} ${ErrorProneChecksDefaultDisabled}")
-
+	errorProneVar("ErrorProneClasspath", &ErrorProneClasspath, ":")
+	errorProneVar("ErrorProneChecksError", &ErrorProneChecksError, " ")
+	errorProneVar("ErrorProneChecksWarning", &ErrorProneChecksWarning, " ")
+	errorProneVar("ErrorProneChecksDefaultDisabled", &ErrorProneChecksDefaultDisabled, " ")
+	errorProneVar("ErrorProneChecksOff", &ErrorProneChecksOff, " ")
+	errorProneVar("ErrorProneFlags", &ErrorProneFlags, " ")
+	pctx.StaticVariable("ErrorProneChecks", strings.Join([]string{
+		"${ErrorProneChecksOff}",
+		"${ErrorProneChecksError}",
+		"${ErrorProneChecksWarning}",
+		"${ErrorProneChecksDefaultDisabled}",
+	}, " "))
 }
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 0e62274..d378877 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -52,18 +52,17 @@
 
 	ctx.Strict("TURBINE", "${TurbineJar}")
 
-	if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") {
-		ctx.Strict("TARGET_JAVAC", "${ErrorProneCmd}")
-		ctx.Strict("HOST_JAVAC", "${ErrorProneCmd}")
-	} else {
-		ctx.Strict("TARGET_JAVAC", "${JavacCmd} ${CommonJdkFlags}")
-		ctx.Strict("HOST_JAVAC", "${JavacCmd} ${CommonJdkFlags}")
+	if ctx.Config().RunErrorProne() {
+		ctx.Strict("ERROR_PRONE_JARS", strings.Join(ErrorProneClasspath, " "))
+		ctx.Strict("ERROR_PRONE_FLAGS", "${ErrorProneFlags}")
+		ctx.Strict("ERROR_PRONE_CHECKS", "${ErrorProneChecks}")
 	}
 
-	if ctx.Config().UseOpenJDK9() {
-		ctx.Strict("JLINK", "${JlinkCmd}")
-		ctx.Strict("JMOD", "${JmodCmd}")
-	}
+	ctx.Strict("TARGET_JAVAC", "${JavacCmd} ${CommonJdkFlags}")
+	ctx.Strict("HOST_JAVAC", "${JavacCmd} ${CommonJdkFlags}")
+
+	ctx.Strict("JLINK", "${JlinkCmd}")
+	ctx.Strict("JMOD", "${JmodCmd}")
 
 	ctx.Strict("SOONG_JAVAC_WRAPPER", "${SoongJavacWrapper}")
 	ctx.Strict("ZIPSYNC", "${ZipSyncCmd}")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index dfba17e..e0e8612 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -99,6 +99,10 @@
 	android.RegisterModuleType("javadoc_host", JavadocHostFactory)
 }
 
+var (
+	srcsLibTag = dependencyTag{name: "sources from javalib"}
+)
+
 type JavadocProperties struct {
 	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
 	// or .aidl files.
@@ -348,6 +352,9 @@
 	}
 
 	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
+	if j.properties.Srcs_lib != nil {
+		ctx.AddDependency(ctx.Module(), srcsLibTag, *j.properties.Srcs_lib)
+	}
 
 	android.ExtractSourcesDeps(ctx, j.properties.Srcs)
 
@@ -447,24 +454,6 @@
 			switch dep := module.(type) {
 			case Dependency:
 				deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
-				if otherName == String(j.properties.Srcs_lib) {
-					srcs := dep.(SrcDependency).CompiledSrcs()
-					whitelistPathPrefixes := make(map[string]bool)
-					j.genWhitelistPathPrefixes(whitelistPathPrefixes)
-					for _, src := range srcs {
-						if _, ok := src.(android.WritablePath); ok { // generated sources
-							deps.srcs = append(deps.srcs, src)
-						} else { // select source path for documentation based on whitelist path prefixs.
-							for k, _ := range whitelistPathPrefixes {
-								if strings.HasPrefix(src.Rel(), k) {
-									deps.srcs = append(deps.srcs, src)
-									break
-								}
-							}
-						}
-					}
-					deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
-				}
 			case SdkLibraryDependency:
 				sdkVersion := String(j.properties.Sdk_version)
 				linkType := javaSdk
@@ -480,6 +469,28 @@
 			default:
 				ctx.ModuleErrorf("depends on non-java module %q", otherName)
 			}
+		case srcsLibTag:
+			switch dep := module.(type) {
+			case Dependency:
+				srcs := dep.(SrcDependency).CompiledSrcs()
+				whitelistPathPrefixes := make(map[string]bool)
+				j.genWhitelistPathPrefixes(whitelistPathPrefixes)
+				for _, src := range srcs {
+					if _, ok := src.(android.WritablePath); ok { // generated sources
+						deps.srcs = append(deps.srcs, src)
+					} else { // select source path for documentation based on whitelist path prefixs.
+						for k, _ := range whitelistPathPrefixes {
+							if strings.HasPrefix(src.Rel(), k) {
+								deps.srcs = append(deps.srcs, src)
+								break
+							}
+						}
+					}
+				}
+				deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
+			default:
+				ctx.ModuleErrorf("depends on non-java module %q", otherName)
+			}
 		case systemModulesTag:
 			if deps.systemModules != nil {
 				panic("Found two system module dependencies")
@@ -529,20 +540,13 @@
 	var bootClasspathArgs, classpathArgs string
 
 	javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), String(j.properties.Sdk_version))
-	if javaVersion == "1.9" || ctx.Config().UseOpenJDK9() {
-		if len(deps.bootClasspath) > 0 {
-			var systemModules classpath
-			if deps.systemModules != nil {
-				systemModules = append(systemModules, deps.systemModules)
-			}
-			bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
-			bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
+	if len(deps.bootClasspath) > 0 {
+		var systemModules classpath
+		if deps.systemModules != nil {
+			systemModules = append(systemModules, deps.systemModules)
 		}
-	} else {
-		if len(deps.bootClasspath.Strings()) > 0 {
-			// For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
-			bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
-		}
+		bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
+		bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
 	}
 	if len(deps.classpath.Strings()) > 0 {
 		classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
@@ -636,6 +640,12 @@
 
 	var bootClasspathArgs string
 	javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), String(d.Javadoc.properties.Sdk_version))
+	// Doclava has problem with "-source 1.9", so override javaVersion when Doclava
+	// is running with EXPERIMENTAL_USE_OPENJDK9=true. And eventually Doclava will be
+	// replaced by Metalava.
+	if !Bool(d.properties.Metalava_enabled) {
+		javaVersion = "1.8"
+	}
 	if javaVersion == "1.9" {
 		if len(deps.bootClasspath) > 0 {
 			var systemModules classpath
diff --git a/java/java.go b/java/java.go
index 969b063..5458ea1 100644
--- a/java/java.go
+++ b/java/java.go
@@ -281,6 +281,9 @@
 
 	// list of extra progurad flag files
 	extraProguardFlagFiles android.Paths
+
+	// list of SDK lib names that this java moudule is exporting
+	exportedSdkLibs []string
 }
 
 func (j *Module) Srcs() android.Paths {
@@ -293,6 +296,7 @@
 	HeaderJars() android.Paths
 	ImplementationJars() android.Paths
 	AidlIncludeDirs() android.Paths
+	ExportedSdkLibs() []string
 }
 
 type SdkLibraryDependency interface {
@@ -327,6 +331,7 @@
 var (
 	staticLibTag     = dependencyTag{name: "staticlib"}
 	libTag           = dependencyTag{name: "javalib"}
+	annoTag          = dependencyTag{name: "annotation processor"}
 	bootClasspathTag = dependencyTag{name: "bootclasspath"}
 	systemModulesTag = dependencyTag{name: "system modules"}
 	frameworkResTag  = dependencyTag{name: "framework-res"}
@@ -517,7 +522,7 @@
 
 	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
 	ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
-	ctx.AddDependency(ctx.Module(), libTag, j.properties.Annotation_processors...)
+	ctx.AddDependency(ctx.Module(), annoTag, j.properties.Annotation_processors...)
 
 	android.ExtractSourcesDeps(ctx, j.properties.Srcs)
 	android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
@@ -598,6 +603,7 @@
 type deps struct {
 	classpath          classpath
 	bootClasspath      classpath
+	processorPath      classpath
 	staticJars         android.Paths
 	staticHeaderJars   android.Paths
 	staticJarResources android.Paths
@@ -714,10 +720,16 @@
 				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
 			case libTag:
 				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
+				// sdk lib names from dependencies are re-exported
+				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
 			case staticLibTag:
 				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
 				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
 				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
+				// sdk lib names from dependencies are re-exported
+				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+			case annoTag:
+				deps.processorPath = append(deps.processorPath, dep.ImplementationJars()...)
 			case frameworkResTag:
 				if ctx.ModuleName() == "framework" {
 					// framework.jar has a one-off dependency on the R.java and Manifest.java files
@@ -748,6 +760,8 @@
 			switch tag {
 			case libTag:
 				deps.classpath = append(deps.classpath, dep.HeaderJars(getLinkType(j, ctx.ModuleName()))...)
+				// names of sdk libs that are directly depended are exported
+				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
 			default:
 				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
 			}
@@ -785,6 +799,8 @@
 		}
 	})
 
+	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
+
 	return deps
 }
 
@@ -827,8 +843,20 @@
 		flags.javacFlags = "$javacFlags"
 	}
 
-	if len(j.properties.Errorprone.Javacflags) > 0 {
-		flags.errorProneExtraJavacFlags = strings.Join(j.properties.Errorprone.Javacflags, " ")
+	if ctx.Config().RunErrorProne() {
+		if config.ErrorProneClasspath == nil {
+			ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
+		}
+
+		errorProneFlags := []string{
+			"-Xplugin:ErrorProne",
+			"${config.ErrorProneChecks}",
+		}
+		errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
+
+		flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
+			"'" + strings.Join(errorProneFlags, " ") + "'"
+		flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
 	}
 
 	// javaVersion flag.
@@ -838,6 +866,7 @@
 	// classpath
 	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
 	flags.classpath = append(flags.classpath, deps.classpath...)
+	flags.processorPath = append(flags.processorPath, deps.processorPath...)
 
 	if len(flags.bootClasspath) == 0 && ctx.Host() && !ctx.Config().TargetOpenJDK9() &&
 		!Bool(j.properties.No_standard_libs) &&
@@ -977,7 +1006,7 @@
 	}
 	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
 		var extraJarDeps android.Paths
-		if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") {
+		if ctx.Config().RunErrorProne() {
 			// If error-prone is enabled, add an additional rule to compile the java files into
 			// a separate set of classes (so that they don't overwrite the normal ones and require
 			// a rebuild when error-prone is turned off).
@@ -1197,6 +1226,10 @@
 	return j.exportAidlIncludeDirs
 }
 
+func (j *Module) ExportedSdkLibs() []string {
+	return j.exportedSdkLibs
+}
+
 var _ logtagsProducer = (*Module)(nil)
 
 func (j *Module) logtags() android.Paths {
@@ -1398,6 +1431,9 @@
 	Sdk_version *string
 
 	Installable *bool
+
+	// List of shared java libs that this module has dependencies to
+	Libs []string
 }
 
 type Import struct {
@@ -1408,6 +1444,7 @@
 
 	classpathFiles        android.Paths
 	combinedClasspathFile android.Path
+	exportedSdkLibs       []string
 }
 
 func (j *Import) Prebuilt() *android.Prebuilt {
@@ -1423,6 +1460,7 @@
 }
 
 func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
+	ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
 }
 
 func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1431,6 +1469,28 @@
 	outputFile := android.PathForModuleOut(ctx, "classes.jar")
 	TransformJarsToJar(ctx, outputFile, "for prebuilts", j.classpathFiles, android.OptionalPath{}, false, nil)
 	j.combinedClasspathFile = outputFile
+
+	ctx.VisitDirectDeps(func(module android.Module) {
+		otherName := ctx.OtherModuleName(module)
+		tag := ctx.OtherModuleDependencyTag(module)
+
+		switch dep := module.(type) {
+		case Dependency:
+			switch tag {
+			case libTag, staticLibTag:
+				// sdk lib names from dependencies are re-exported
+				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+			}
+		case SdkLibraryDependency:
+			switch tag {
+			case libTag:
+				// names of sdk libs that are directly depended are exported
+				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
+			}
+		}
+	})
+
+	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
 }
 
 var _ Dependency = (*Import)(nil)
@@ -1447,6 +1507,10 @@
 	return nil
 }
 
+func (j *Import) ExportedSdkLibs() []string {
+	return j.exportedSdkLibs
+}
+
 var _ android.PrebuiltInterface = (*Import)(nil)
 
 func ImportFactory() android.Module {
diff --git a/java/java_test.go b/java/java_test.go
index 1678296..96bf224 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1095,6 +1095,12 @@
 			libs: ["foo", "bar"],
 			sdk_version: "system_current",
 		}
+		java_library {
+		    name: "qux",
+		    srcs: ["c.java"],
+		    libs: ["baz"],
+		    sdk_version: "system_current",
+		}
 		`)
 
 	// check the existence of the internal modules
@@ -1127,4 +1133,13 @@
 		t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
 			"foo.stubs.jar")
 	}
+
+	// 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()
+		if len(sdkLibs) != 2 || !android.InList("foo", sdkLibs) || !android.InList("bar", sdkLibs) {
+			t.Errorf("qux should export \"foo\" and \"bar\" but exports %v", sdkLibs)
+		}
+	}
 }
diff --git a/java/sdk_library.go b/java/sdk_library.go
index aee528f..55da533 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -67,9 +67,8 @@
 // classpath at runtime if requested via <uses-library>.
 //
 // TODO: these are big features that are currently missing
-// 1) ensuring that apps have appropriate <uses-library> tag
-// 2) disallowing linking to the runtime shared lib
-// 3) HTML generation
+// 1) disallowing linking to the runtime shared lib
+// 2) HTML generation
 
 func init() {
 	android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
diff --git a/python/python.go b/python/python.go
index 4b9111f..feb17da 100644
--- a/python/python.go
+++ b/python/python.go
@@ -574,32 +574,39 @@
 		destToPyData[path.dest] = path.src.String()
 	}
 
+	seen := make(map[android.Module]bool)
+
 	// visit all its dependencies in depth first.
-	ctx.VisitDepsDepthFirst(func(module android.Module) {
-		if ctx.OtherModuleDependencyTag(module) != pythonLibTag {
-			return
+	ctx.WalkDeps(func(child, parent android.Module) bool {
+		if ctx.OtherModuleDependencyTag(child) != pythonLibTag {
+			return false
 		}
+		if seen[child] {
+			return false
+		}
+		seen[child] = true
 		// Python modules only can depend on Python libraries.
-		if !isPythonLibModule(module) {
+		if !isPythonLibModule(child) {
 			panic(fmt.Errorf(
 				"the dependency %q of module %q is not Python library!",
-				ctx.ModuleName(), ctx.OtherModuleName(module)))
+				ctx.ModuleName(), ctx.OtherModuleName(child)))
 		}
-		if dep, ok := module.(PythonDependency); ok {
+		if dep, ok := child.(PythonDependency); ok {
 			srcs := dep.GetSrcsPathMappings()
 			for _, path := range srcs {
 				if !fillInMap(ctx, destToPySrcs,
-					path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(module)) {
+					path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child)) {
 					continue
 				}
 			}
 			data := dep.GetDataPathMappings()
 			for _, path := range data {
 				fillInMap(ctx, destToPyData,
-					path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(module))
+					path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child))
 			}
 			p.depsSrcsZips = append(p.depsSrcsZips, dep.GetSrcsZip())
 		}
+		return true
 	})
 }
 
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index f34f6c3..6af0ca9 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -34,14 +34,25 @@
   return children
 
 
+def find_child_with_attribute(element, tag_name, namespace_uri,
+                              attr_name, value):
+  for child in get_children_with_tag(element, tag_name):
+    attr = child.getAttributeNodeNS(namespace_uri, attr_name)
+    if attr is not None and attr.value == value:
+      return child
+  return None
+
+
 def parse_args():
   """Parse commandline arguments."""
 
   parser = argparse.ArgumentParser()
   parser.add_argument('--minSdkVersion', default='', dest='min_sdk_version',
                       help='specify minSdkVersion used by the build system')
+  parser.add_argument('--uses-library', dest='uses_libraries', action='append',
+                      help='specify additional <uses-library> tag to add')
   parser.add_argument('input', help='input AndroidManifest.xml file')
-  parser.add_argument('output', help='input AndroidManifest.xml file')
+  parser.add_argument('output', help='output AndroidManifest.xml file')
   return parser.parse_args()
 
 
@@ -104,6 +115,17 @@
     return b_is_int
 
 
+def get_indent(element, default_level):
+  indent = ''
+  if element is not None and element.nodeType == minidom.Node.TEXT_NODE:
+    text = element.nodeValue
+    indent = text[:len(text)-len(text.lstrip())]
+  if not indent or indent == '\n':
+    # 1 indent = 4 space
+    indent = '\n' + (' ' * default_level * 4)
+  return indent
+
+
 def raise_min_sdk_version(doc, requested):
   """Ensure the manifest contains a <uses-sdk> tag with a minSdkVersion.
 
@@ -124,14 +146,7 @@
     element = uses_sdk[0]
   else:
     element = doc.createElement('uses-sdk')
-    indent = ''
-    first = manifest.firstChild
-    if first is not None and first.nodeType == minidom.Node.TEXT_NODE:
-      text = first.nodeValue
-      indent = text[:len(text)-len(text.lstrip())]
-    if not indent or indent == '\n':
-      indent = '\n    '
-
+    indent = get_indent(manifest.firstChild, 1)
     manifest.insertBefore(element, manifest.firstChild)
 
     # Insert an indent before uses-sdk to line it up with the indentation of the
@@ -150,6 +165,55 @@
     min_attr.value = requested
 
 
+def add_uses_libraries(doc, new_uses_libraries):
+  """Add additional <uses-library> tags with android:required=true.
+
+  Args:
+    doc: The XML document. May be modified by this function.
+    new_uses_libraries: The names of libraries to be added by this function.
+  Raises:
+    RuntimeError: Invalid manifest
+  """
+
+  manifest = parse_manifest(doc)
+  elems = get_children_with_tag(manifest, 'application')
+  application = elems[0] if len(elems) == 1 else None
+  if len(elems) > 1:
+    raise RuntimeError('found multiple <application> tags')
+  elif not elems:
+    application = doc.createElement('application')
+    indent = get_indent(manifest.firstChild, 1)
+    first = manifest.firstChild
+    manifest.insertBefore(doc.createTextNode(indent), first)
+    manifest.insertBefore(application, first)
+
+  indent = get_indent(application.firstChild, 2)
+
+  last = application.lastChild
+  if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
+    last = None
+
+  for name in new_uses_libraries:
+    if find_child_with_attribute(application, 'uses-library', android_ns,
+                                 'name', name) is not None:
+      # If the uses-library tag of the same 'name' attribute value exists,
+      # respect it.
+      continue
+
+    ul = doc.createElement('uses-library')
+    ul.setAttributeNS(android_ns, 'android:name', name)
+    ul.setAttributeNS(android_ns, 'android:required', 'true')
+
+    application.insertBefore(doc.createTextNode(indent), last)
+    application.insertBefore(ul, last)
+
+  # align the closing tag with the opening tag if it's not
+  # indented
+  if application.lastChild.nodeType != minidom.Node.TEXT_NODE:
+    indent = get_indent(application.previousSibling, 1)
+    application.appendChild(doc.createTextNode(indent))
+
+
 def write_xml(f, doc):
   f.write('<?xml version="1.0" encoding="utf-8"?>\n')
   for node in doc.childNodes:
@@ -168,6 +232,9 @@
     if args.min_sdk_version:
       raise_min_sdk_version(doc, args.min_sdk_version)
 
+    if args.uses_libraries:
+      add_uses_libraries(doc, args.uses_libraries)
+
     with open(args.output, 'wb') as f:
       write_xml(f, doc)
 
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index ccfa8fb..54a3784 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -158,5 +158,92 @@
 
     self.assertEqual(output, expected)
 
+
+class AddUsesLibrariesTest(unittest.TestCase):
+  """Unit tests for add_uses_libraries function."""
+
+  def run_test(self, input_manifest, new_uses_libraries):
+    doc = minidom.parseString(input_manifest)
+    manifest_fixer.add_uses_libraries(doc, new_uses_libraries)
+    output = StringIO.StringIO()
+    manifest_fixer.write_xml(output, doc)
+    return output.getvalue()
+
+  manifest_tmpl = (
+      '<?xml version="1.0" encoding="utf-8"?>\n'
+      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+      '    <application>\n'
+      '%s'
+      '    </application>\n'
+      '</manifest>\n')
+
+  def uses_libraries(self, name_required_pairs):
+    ret = ''
+    for name, required in name_required_pairs:
+      ret += (
+          '        <uses-library android:name="%s" android:required="%s"/>\n'
+      ) % (name, required)
+
+    return ret
+
+  def test_empty(self):
+    """Empty new_uses_libraries must not touch the manifest."""
+    manifest_input = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'false')])
+    expected = manifest_input
+    output = self.run_test(manifest_input, [])
+    self.assertEqual(output, expected)
+
+  def test_not_overwrite(self):
+    """new_uses_libraries must not overwrite existing tags."""
+    manifest_input = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'false')])
+    expected = manifest_input
+    output = self.run_test(manifest_input, ['foo', 'bar'])
+    self.assertEqual(output, expected)
+
+  def test_add(self):
+    """New names are added with 'required:true'."""
+    manifest_input = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'false')])
+    expected = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'false'),
+        ('baz', 'true'),
+        ('qux', 'true')])
+    output = self.run_test(manifest_input, ['bar', 'baz', 'qux'])
+    self.assertEqual(output, expected)
+
+  def test_no_application(self):
+    """When there is no <application> tag, the tag is added."""
+    manifest_input = (
+        '<?xml version="1.0" encoding="utf-8"?>\n'
+        '<manifest xmlns:android='
+        '"http://schemas.android.com/apk/res/android">\n'
+        '</manifest>\n')
+    expected = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'true')])
+    output = self.run_test(manifest_input, ['foo', 'bar'])
+    self.assertEqual(output, expected)
+
+  def test_empty_application(self):
+    """Even when here is an empty <application/> tag, the libs are added."""
+    manifest_input = (
+        '<?xml version="1.0" encoding="utf-8"?>\n'
+        '<manifest xmlns:android='
+        '"http://schemas.android.com/apk/res/android">\n'
+        '    <application/>\n'
+        '</manifest>\n')
+    expected = self.manifest_tmpl % self.uses_libraries([
+        ('foo', 'true'),
+        ('bar', 'true')])
+    output = self.run_test(manifest_input, ['foo', 'bar'])
+    self.assertEqual(output, expected)
+
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/ui/build/config.go b/ui/build/config.go
index 6f2d24a..d0378ec 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -50,6 +50,7 @@
 	targetDevice    string
 	targetDeviceDir string
 
+	pdkBuild       bool
 	brokenDupRules bool
 
 	pathReplaced bool
@@ -163,19 +164,7 @@
 		if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok {
 			return override
 		}
-		v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9")
-		if !ok {
-			v2, ok2 := ret.environ.Get("RUN_ERROR_PRONE")
-			if ok2 && (v2 == "true") {
-				v = "false"
-			} else {
-				v = "1.8"
-			}
-		}
-		if v != "false" {
-			return java9Home
-		}
-		return java8Home
+		return java9Home
 	}()
 	absJavaHome := absPath(ctx, javaHome)
 
@@ -579,3 +568,11 @@
 func (c *configImpl) TargetDeviceDir() string {
 	return c.targetDeviceDir
 }
+
+func (c *configImpl) SetPdkBuild(pdk bool) {
+	c.pdkBuild = pdk
+}
+
+func (c *configImpl) IsPdkBuild() bool {
+	return c.pdkBuild
+}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index cc9e742..8429a8a 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -162,6 +162,11 @@
 
 		// Whether --werror_overriding_commands will work
 		"BUILD_BROKEN_DUP_RULES",
+
+		// Not used, but useful to be in the soong.log
+		"BUILD_BROKEN_ANDROIDMK_EXPORTS",
+		"BUILD_BROKEN_DUP_COPY_HEADERS",
+		"BUILD_BROKEN_PHONY_TARGETS",
 	}, exportEnvVars...), BannerVars...)
 
 	make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
@@ -187,5 +192,6 @@
 	config.SetTargetDevice(make_vars["TARGET_DEVICE"])
 	config.SetTargetDeviceDir(make_vars["TARGET_DEVICE_DIR"])
 
+	config.SetPdkBuild(make_vars["TARGET_BUILD_PDK"] == "true")
 	config.SetBuildBrokenDupRules(make_vars["BUILD_BROKEN_DUP_RULES"] != "false")
 }
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 743da4a..7635c10 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -83,6 +83,11 @@
 		"-f", "build/make/core/main.mk",
 	}
 
+	// PDK builds still uses a few implicit rules
+	if !config.IsPdkBuild() {
+		args = append(args, "--werror_implicit_rules")
+	}
+
 	if !config.BuildBrokenDupRules() {
 		args = append(args, "--werror_overriding_commands")
 	}
diff --git a/zip/zip.go b/zip/zip.go
index b7e3764..a89fa9f 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -788,13 +788,16 @@
 		Name: rel,
 	}
 	fileHeader.SetModTime(z.time)
-	fileHeader.SetMode(0700 | os.ModeSymlink)
+	fileHeader.SetMode(0777 | os.ModeSymlink)
 
 	dest, err := os.Readlink(file)
 	if err != nil {
 		return err
 	}
 
+	fileHeader.UncompressedSize64 = uint64(len(dest))
+	fileHeader.CRC32 = crc32.ChecksumIEEE([]byte(dest))
+
 	ze := make(chan *zipEntry, 1)
 	futureReaders := make(chan chan io.Reader, 1)
 	futureReader := make(chan io.Reader, 1)