Merge "Propagate recovery_available property through to sdk snapshot"
diff --git a/android/arch.go b/android/arch.go
index 66edf7e..ba113b2 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -23,6 +23,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -698,13 +699,31 @@
 	}
 }
 
-func osMutator(mctx BottomUpMutatorContext) {
+func osMutator(bpctx blueprint.BottomUpMutatorContext) {
 	var module Module
 	var ok bool
-	if module, ok = mctx.Module().(Module); !ok {
+	if module, ok = bpctx.Module().(Module); !ok {
+		if bootstrap.IsBootstrapModule(bpctx.Module()) {
+			// Bootstrap Go modules are always the build OS or linux bionic.
+			config := bpctx.Config().(Config)
+			osNames := []string{config.BuildOSTarget.OsVariation()}
+			for _, hostCrossTarget := range config.Targets[LinuxBionic] {
+				if hostCrossTarget.Arch.ArchType == config.BuildOSTarget.Arch.ArchType {
+					osNames = append(osNames, hostCrossTarget.OsVariation())
+				}
+			}
+			osNames = FirstUniqueStrings(osNames)
+			bpctx.CreateVariations(osNames...)
+		}
 		return
 	}
 
+	// Bootstrap Go module support above requires this mutator to be a
+	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
+	// filters out non-Soong modules.  Now that we've handled them, create a
+	// normal android.BottomUpMutatorContext.
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+
 	base := module.base()
 
 	if !base.ArchSpecific() {
@@ -828,13 +847,23 @@
 //
 // Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
 // but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
-func archMutator(mctx BottomUpMutatorContext) {
+func archMutator(bpctx blueprint.BottomUpMutatorContext) {
 	var module Module
 	var ok bool
-	if module, ok = mctx.Module().(Module); !ok {
+	if module, ok = bpctx.Module().(Module); !ok {
+		if bootstrap.IsBootstrapModule(bpctx.Module()) {
+			// Bootstrap Go modules are always the build architecture.
+			bpctx.CreateVariations(bpctx.Config().(Config).BuildOSTarget.ArchVariation())
+		}
 		return
 	}
 
+	// Bootstrap Go module support above requires this mutator to be a
+	// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
+	// filters out non-Soong modules.  Now that we've handled them, create a
+	// normal android.BottomUpMutatorContext.
+	mctx := bottomUpMutatorContextFactory(bpctx, module, false)
+
 	base := module.base()
 
 	if !base.ArchSpecific() {
@@ -912,7 +941,7 @@
 	modules := mctx.CreateVariations(targetNames...)
 	for i, m := range modules {
 		addTargetProperties(m, targets[i], multiTargets, i == 0)
-		m.(Module).base().setArchProperties(mctx)
+		m.base().setArchProperties(mctx)
 	}
 }
 
diff --git a/android/mutator.go b/android/mutator.go
index 40e61de..5212553 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -75,6 +75,7 @@
 type RegisterMutatorsContext interface {
 	TopDown(name string, m TopDownMutator) MutatorHandle
 	BottomUp(name string, m BottomUpMutator) MutatorHandle
+	BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
 }
 
 type RegisterMutatorFunc func(RegisterMutatorsContext)
@@ -143,9 +144,9 @@
 }
 
 func registerArchMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("os", osMutator).Parallel()
+	ctx.BottomUpBlueprint("os", osMutator).Parallel()
 	ctx.BottomUp("image", imageMutator).Parallel()
-	ctx.BottomUp("arch", archMutator).Parallel()
+	ctx.BottomUpBlueprint("arch", archMutator).Parallel()
 }
 
 var preDeps = []RegisterMutatorFunc{
@@ -225,16 +226,21 @@
 	finalPhase bool
 }
 
+func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
+	finalPhase bool) BottomUpMutatorContext {
+
+	return &bottomUpMutatorContext{
+		bp:                ctx,
+		baseModuleContext: a.base().baseModuleContextFactory(ctx),
+		finalPhase:        finalPhase,
+	}
+}
+
 func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
 	finalPhase := x.finalPhase
 	f := func(ctx blueprint.BottomUpMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
-			actx := &bottomUpMutatorContext{
-				bp:                ctx,
-				baseModuleContext: a.base().baseModuleContextFactory(ctx),
-				finalPhase:        finalPhase,
-			}
-			m(actx)
+			m(bottomUpMutatorContextFactory(ctx, a, finalPhase))
 		}
 	}
 	mutator := &mutator{name: name, bottomUpMutator: f}
@@ -242,6 +248,12 @@
 	return mutator
 }
 
+func (x *registerMutatorsContext) BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle {
+	mutator := &mutator{name: name, bottomUpMutator: m}
+	x.mutators = append(x.mutators, mutator)
+	return mutator
+}
+
 func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
 	f := func(ctx blueprint.TopDownMutatorContext) {
 		if a, ok := ctx.Module().(Module); ok {
diff --git a/apex/androidmk.go b/apex/androidmk.go
index af2ec3d..1b53a67 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -36,7 +36,9 @@
 	return a.androidMkForType()
 }
 
-func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, moduleDir string) []string {
+func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, moduleDir string,
+	apexAndroidMkData android.AndroidMkData) []string {
+
 	// apexBundleName comes from the 'name' property; apexName comes from 'apex_name' property.
 	// An apex is installed to /system/apex/<apexBundleName> and is activated at /apex/<apexName>
 	// In many cases, the two names are the same, but could be different in general.
@@ -236,6 +238,17 @@
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
 			if fi.builtFile == a.manifestPbOut && apexType == flattenedApex {
 				if a.primaryApexType {
+					// To install companion files (init_rc, vintf_fragments)
+					// Copy some common properties of apexBundle to apex_manifest
+					commonProperties := []string{
+						"LOCAL_INIT_RC", "LOCAL_VINTF_FRAGMENTS",
+					}
+					for _, name := range commonProperties {
+						if value, ok := apexAndroidMkData.Entries.EntryMap[name]; ok {
+							fmt.Fprintln(w, name+" := "+strings.Join(value, " "))
+						}
+					}
+
 					// Make apex_manifest.pb module for this APEX to override all other
 					// modules in the APEXes being overridden by this APEX
 					var patterns []string
@@ -294,7 +307,7 @@
 			apexType := a.properties.ApexType
 			if a.installable() {
 				apexName := proptools.StringDefault(a.properties.Apex_name, name)
-				moduleNames = a.androidMkForFiles(w, name, apexName, moduleDir)
+				moduleNames = a.androidMkForFiles(w, name, apexName, moduleDir, data)
 			}
 
 			if apexType == flattenedApex {
diff --git a/cc/compiler.go b/cc/compiler.go
index f504c38..c268dec 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -573,10 +573,12 @@
 	return compiler.useApexNameMacro()
 }
 
+var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
+
 // makeDefineString transforms a name of an APEX module into a value to be used as value for C define
 // For example, com.android.foo => COM_ANDROID_FOO
 func makeDefineString(name string) string {
-	return strings.ReplaceAll(strings.ToUpper(name), ".", "_")
+	return invalidDefineCharRegex.ReplaceAllString(strings.ToUpper(name), "_")
 }
 
 var gnuToCReplacer = strings.NewReplacer("gnu", "c")
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index cd0a508..b5b5553 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -49,7 +49,11 @@
 
 	windowsClangCppflags = []string{}
 
-	windowsX86ClangCppflags = []string{}
+	windowsX86ClangCppflags = []string{
+		// Use SjLj exceptions for 32-bit.  libgcc_eh implements SjLj
+		// exception model for 32-bit.
+		"-fsjlj-exceptions",
+	}
 
 	windowsX8664ClangCppflags = []string{}
 
diff --git a/cc/stl.go b/cc/stl.go
index 4e74c7f..e18fe95 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -239,11 +239,6 @@
 			flags.Local.CppFlags = append(flags.Local.CppFlags, "-nostdinc++")
 			flags.extraLibFlags = append(flags.extraLibFlags, "-nostdlib++")
 			if ctx.Windows() {
-				// Use SjLj exceptions for 32-bit.  libgcc_eh implements SjLj
-				// exception model for 32-bit.
-				if ctx.Arch().ArchType == android.X86 {
-					flags.Local.CppFlags = append(flags.Local.CppFlags, "-fsjlj-exceptions")
-				}
 				flags.Local.CppFlags = append(flags.Local.CppFlags,
 					// Disable visiblity annotations since we're using static
 					// libc++.
diff --git a/java/androidmk.go b/java/androidmk.go
index a503d2a..65c44a3 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -509,53 +509,14 @@
 func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries {
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "JAVA_LIBRARIES",
-		OutputFile: android.OptionalPathForPath(ddoc.stubsSrcJar),
+		OutputFile: android.OptionalPathForPath(ddoc.Javadoc.docZip),
 		Include:    "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(entries *android.AndroidMkEntries) {
-				if BoolDefault(ddoc.Javadoc.properties.Installable, true) && ddoc.Javadoc.docZip != nil {
+				if ddoc.Javadoc.docZip != nil {
 					entries.SetPath("LOCAL_DROIDDOC_DOC_ZIP", ddoc.Javadoc.docZip)
 				}
-				if ddoc.Javadoc.stubsSrcJar != nil {
-					entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", ddoc.Javadoc.stubsSrcJar)
-				}
-			},
-		},
-		ExtraFooters: []android.AndroidMkExtraFootersFunc{
-			func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
-				if ddoc.checkCurrentApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-check-current-api")
-					fmt.Fprintln(w, ddoc.Name()+"-check-current-api:",
-						ddoc.checkCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: checkapi")
-					fmt.Fprintln(w, "checkapi:",
-						ddoc.checkCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: droidcore")
-					fmt.Fprintln(w, "droidcore: checkapi")
-				}
-				if ddoc.updateCurrentApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-update-current-api")
-					fmt.Fprintln(w, ddoc.Name()+"-update-current-api:",
-						ddoc.updateCurrentApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: update-api")
-					fmt.Fprintln(w, "update-api:",
-						ddoc.updateCurrentApiTimestamp.String())
-				}
-				if ddoc.checkLastReleasedApiTimestamp != nil {
-					fmt.Fprintln(w, ".PHONY:", ddoc.Name()+"-check-last-released-api")
-					fmt.Fprintln(w, ddoc.Name()+"-check-last-released-api:",
-						ddoc.checkLastReleasedApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: checkapi")
-					fmt.Fprintln(w, "checkapi:",
-						ddoc.checkLastReleasedApiTimestamp.String())
-
-					fmt.Fprintln(w, ".PHONY: droidcore")
-					fmt.Fprintln(w, "droidcore: checkapi")
-				}
+				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !BoolDefault(ddoc.Javadoc.properties.Installable, true))
 			},
 		},
 	}}
diff --git a/java/dex.go b/java/dex.go
index 15b4431..21a5926 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -38,6 +38,10 @@
 		// True if the module containing this has it set by default.
 		EnabledByDefault bool `blueprint:"mutated"`
 
+		// If true, runs R8 in Proguard compatibility mode (default).
+		// Otherwise, runs R8 in full mode.
+		Proguard_compatibility *bool
+
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
 		// false for libraries and tests.
 		Shrink *bool
@@ -113,7 +117,6 @@
 			`rm -f "$outDict" && rm -rf "${outUsageDir}" && ` +
 			`mkdir -p $$(dirname ${outUsage}) && ` +
 			`$r8Template${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
-			`--force-proguard-compatibility ` +
 			`--no-data-resources ` +
 			`-printmapping ${outDict} ` +
 			`-printusage ${outUsage} ` +
@@ -230,6 +233,10 @@
 
 	r8Flags = append(r8Flags, opt.Proguard_flags...)
 
+	if BoolDefault(opt.Proguard_compatibility, true) {
+		r8Flags = append(r8Flags, "--force-proguard-compatibility")
+	}
+
 	// TODO(ccross): Don't shrink app instrumentation tests by default.
 	if !Bool(opt.Shrink) {
 		r8Flags = append(r8Flags, "-dontshrink")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 2219ec9..7073eff 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -70,10 +70,6 @@
 	// or .aidl files.
 	Srcs []string `android:"path,arch_variant"`
 
-	// list of directories rooted at the Android.bp file that will
-	// be added to the search paths for finding source files when passing package names.
-	Local_sourcepaths []string
-
 	// list of source files that should not be used to build the Java module.
 	// This is most useful in the arch/multilib variants to remove non-common files
 	// filegroup or genrule can be included within this property.
@@ -175,10 +171,6 @@
 	// resources output directory under out/soong/.intermediates.
 	Resourcesoutdir *string
 
-	// if set to true, collect the values used by the Dev tools and
-	// write them in files packaged with the SDK. Defaults to false.
-	Write_sdk_values *bool
-
 	// index.html under current module will be copied to docs out dir, if not null.
 	Static_doc_index_redirect *string `android:"path"`
 
@@ -195,22 +187,6 @@
 	// the generated removed API filename by Doclava.
 	Removed_api_filename *string
 
-	// the generated removed Dex API filename by Doclava.
-	Removed_dex_api_filename *string
-
-	// if set to false, don't allow droiddoc to generate stubs source files. Defaults to false.
-	Create_stubs *bool
-
-	Check_api struct {
-		Last_released ApiToCheck
-
-		Current ApiToCheck
-
-		// do not perform API check against Last_released, in the case that both two specified API
-		// files by Last_released are modules which don't exist.
-		Ignore_missing_latest_api *bool `blueprint:"mutated"`
-	}
-
 	// if set to true, generate docs through Dokka instead of Doclava.
 	Dokka_enabled *bool
 
@@ -639,10 +615,9 @@
 	j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
 	j.srcFiles = append(j.srcFiles, deps.srcs...)
 
-	if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
-		j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
+	if len(j.srcFiles) > 0 {
+		j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
 	}
-	j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
 
 	j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
 	argFilesMap := map[string]string{}
@@ -748,17 +723,7 @@
 type Droiddoc struct {
 	Javadoc
 
-	properties        DroiddocProperties
-	apiFile           android.WritablePath
-	privateApiFile    android.WritablePath
-	removedApiFile    android.WritablePath
-	removedDexApiFile android.WritablePath
-
-	checkCurrentApiTimestamp      android.WritablePath
-	updateCurrentApiTimestamp     android.WritablePath
-	checkLastReleasedApiTimestamp android.WritablePath
-
-	apiFilePath android.Path
+	properties DroiddocProperties
 }
 
 // droiddoc converts .java source files to documentation using doclava or dokka.
@@ -783,17 +748,18 @@
 	return module
 }
 
-func (d *Droiddoc) ApiFilePath() android.Path {
-	return d.apiFilePath
+func (d *Droiddoc) OutputFiles(tag string) (android.Paths, error) {
+	switch tag {
+	case "", ".docs.zip":
+		return android.Paths{d.Javadoc.docZip}, nil
+	default:
+		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+	}
 }
 
 func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
 	d.Javadoc.addDeps(ctx)
 
-	if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
-		ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
-	}
-
 	if String(d.properties.Custom_template) != "" {
 		ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
 	}
@@ -873,41 +839,6 @@
 	}
 }
 
-func (d *Droiddoc) createStubs() bool {
-	return BoolDefault(d.properties.Create_stubs, false)
-}
-
-func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
-	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
-		apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
-		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(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)
-	}
-
-	if String(d.properties.Removed_dex_api_filename) != "" {
-		d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
-		cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
-	}
-
-	if d.createStubs() {
-		cmd.FlagWithArg("-stubs ", stubsDir.String())
-	}
-
-	if Bool(d.properties.Write_sdk_values) {
-		cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
-	}
-}
-
 func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
 	if String(d.properties.Static_doc_index_redirect) != "" {
 		staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
@@ -1010,22 +941,15 @@
 	deps := d.Javadoc.collectDeps(ctx)
 
 	d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
-	d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
 
 	jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
 	doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
-	java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
-	checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
 
 	outDir := android.PathForModuleOut(ctx, "out")
 	srcJarDir := android.PathForModuleOut(ctx, "srcjars")
-	stubsDir := android.PathForModuleOut(ctx, "stubsDir")
 
 	rule := android.NewRuleBuilder()
 
-	rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
-	rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
-
 	srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
 
 	var cmd *android.RuleBuilderCommand
@@ -1036,8 +960,6 @@
 			deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
 	}
 
-	d.stubsFlags(ctx, cmd, stubsDir)
-
 	cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
 
 	if d.properties.Compat_config != nil {
@@ -1067,120 +989,11 @@
 		FlagWithArg("-C ", outDir.String()).
 		FlagWithArg("-D ", outDir.String())
 
-	rule.Command().
-		BuiltTool(ctx, "soong_zip").
-		Flag("-write_if_changed").
-		Flag("-jar").
-		FlagWithOutput("-o ", d.stubsSrcJar).
-		FlagWithArg("-C ", stubsDir.String()).
-		FlagWithArg("-D ", stubsDir.String())
-
 	rule.Restat()
 
 	zipSyncCleanupCmd(rule, srcJarDir)
 
 	rule.Build(pctx, ctx, "javadoc", desc)
-
-	if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
-		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
-		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
-
-		d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
-
-		rule := android.NewRuleBuilder()
-
-		rule.Command().Text("( true")
-
-		rule.Command().
-			BuiltTool(ctx, "apicheck").
-			Flag("-JXmx1024m").
-			FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
-			OptionalFlag(d.properties.Check_api.Current.Args).
-			Input(apiFile).
-			Input(d.apiFile).
-			Input(removedApiFile).
-			Input(d.removedApiFile)
-
-		msg := fmt.Sprintf(`\n******************************\n`+
-			`You have tried to change the API from what has been previously approved.\n\n`+
-			`To make these errors go away, you have two choices:\n`+
-			`   1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
-			`      errors above.\n\n`+
-			`   2. You can update current.txt by executing the following command:\n`+
-			`         make %s-update-current-api\n\n`+
-			`      To submit the revised current.txt to the main Android repository,\n`+
-			`      you will need approval.\n`+
-			`******************************\n`, ctx.ModuleName())
-
-		rule.Command().
-			Text("touch").Output(d.checkCurrentApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
-
-		d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
-
-		// update API rule
-		rule = android.NewRuleBuilder()
-
-		rule.Command().Text("( true")
-
-		rule.Command().
-			Text("cp").Flag("-f").
-			Input(d.apiFile).Flag(apiFile.String())
-
-		rule.Command().
-			Text("cp").Flag("-f").
-			Input(d.removedApiFile).Flag(removedApiFile.String())
-
-		msg = "failed to update public API"
-
-		rule.Command().
-			Text("touch").Output(d.updateCurrentApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
-	}
-
-	if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
-		apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
-		removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
-
-		d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
-
-		rule := android.NewRuleBuilder()
-
-		rule.Command().
-			Text("(").
-			BuiltTool(ctx, "apicheck").
-			Flag("-JXmx1024m").
-			FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
-			OptionalFlag(d.properties.Check_api.Last_released.Args).
-			Input(apiFile).
-			Input(d.apiFile).
-			Input(removedApiFile).
-			Input(d.removedApiFile)
-
-		msg := `\n******************************\n` +
-			`You have tried to change the API from what has been previously released in\n` +
-			`an SDK.  Please fix the errors listed above.\n` +
-			`******************************\n`
-
-		rule.Command().
-			Text("touch").Output(d.checkLastReleasedApiTimestamp).
-			Text(") || (").
-			Text("echo").Flag("-e").Flag(`"` + msg + `"`).
-			Text("; exit 38").
-			Text(")")
-
-		rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
-	}
 }
 
 //
diff --git a/java/java_test.go b/java/java_test.go
index 3f7bab1..9e63577 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1097,16 +1097,26 @@
 		    srcs: ["bar-doc/IBar.aidl"],
 		    path: "bar-doc",
 		}
-		droiddoc {
-		    name: "bar-doc",
+		droidstubs {
+		    name: "bar-stubs",
 		    srcs: [
 		        "bar-doc/a.java",
-		        "bar-doc/IFoo.aidl",
-		        ":bar-doc-aidl-srcs",
 		    ],
 		    exclude_srcs: [
 		        "bar-doc/b.java"
 		    ],
+		    api_levels_annotations_dirs: [
+		      "droiddoc-templates-sdk",
+		    ],
+		    api_levels_annotations_enabled: true,
+		}
+		droiddoc {
+		    name: "bar-doc",
+		    srcs: [
+		        ":bar-stubs",
+		        "bar-doc/IFoo.aidl",
+		        ":bar-doc-aidl-srcs",
+		    ],
 		    custom_template: "droiddoc-templates-sdk",
 		    hdf: [
 		        "android.whichdoc offline",
@@ -1123,23 +1133,29 @@
 			"bar-doc/a.java": nil,
 			"bar-doc/b.java": nil,
 		})
-	barDocModule := ctx.ModuleForTests("bar-doc", "android_common")
-	barDoc := barDocModule.Rule("javadoc")
-	notExpected := " -stubs "
-	if strings.Contains(barDoc.RuleParams.Command, notExpected) {
-		t.Errorf("bar-doc command contains flag %q to create stubs, but should not", notExpected)
+	barStubs := ctx.ModuleForTests("bar-stubs", "android_common")
+	barStubsOutputs, err := barStubs.Module().(*Droidstubs).OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error %q retrieving \"bar-stubs\" output file", err)
+	}
+	if len(barStubsOutputs) != 1 {
+		t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
 	}
 
-	var javaSrcs []string
-	for _, i := range barDoc.Inputs {
-		javaSrcs = append(javaSrcs, i.Base())
-	}
-	if len(javaSrcs) != 1 || javaSrcs[0] != "a.java" {
-		t.Errorf("inputs of bar-doc must be []string{\"a.java\"}, but was %#v.", javaSrcs)
+	barStubsOutput := barStubsOutputs[0]
+	barDoc := ctx.ModuleForTests("bar-doc", "android_common")
+	javaDoc := barDoc.Rule("javadoc")
+	if g, w := javaDoc.Implicits.Strings(), barStubsOutput.String(); !inList(w, g) {
+		t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
 	}
 
-	aidl := barDocModule.Rule("aidl")
-	if g, w := barDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
+	expected := "-sourcepath " + buildDir + "/.intermediates/bar-doc/android_common/srcjars "
+	if !strings.Contains(javaDoc.RuleParams.Command, expected) {
+		t.Errorf("bar-doc command does not contain flag %q, but should\n%q", expected, javaDoc.RuleParams.Command)
+	}
+
+	aidl := barDoc.Rule("aidl")
+	if g, w := javaDoc.Implicits.Strings(), aidl.Output.String(); !inList(w, g) {
 		t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
 	}
 
@@ -1159,16 +1175,26 @@
 		    srcs: ["bar-doc/IBar.aidl"],
 		    path: "bar-doc",
 		}
-		droiddoc {
-		    name: "bar-doc",
+		droidstubs {
+		    name: "bar-stubs",
 		    srcs: [
 		        "bar-doc/a.java",
-		        "bar-doc/IFoo.aidl",
-		        ":bar-doc-aidl-srcs",
 		    ],
 		    exclude_srcs: [
 		        "bar-doc/b.java"
 		    ],
+		    api_levels_annotations_dirs: [
+		      "droiddoc-templates-sdk",
+		    ],
+		    api_levels_annotations_enabled: true,
+		}
+		droiddoc {
+		    name: "bar-doc",
+		    srcs: [
+		        ":bar-stubs",
+		        "bar-doc/IFoo.aidl",
+		        ":bar-doc-aidl-srcs",
+		    ],
 		    custom_template: "droiddoc-templates-sdk",
 		    hdf: [
 		        "android.whichdoc offline",