Merge "Add support for generating Compdb file"
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 9bcb783..5824168 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -243,6 +243,7 @@
 			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
 				strings.Join(benchmark.Properties.Test_suites, " "))
 		}
+		fmt.Fprintln(w, "LOCAL_NATIVE_BENCHMARK := true")
 	})
 
 	androidMkWriteTestData(benchmark.data, ctx, ret)
diff --git a/cc/cc.go b/cc/cc.go
index 1905990..9722cf0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -193,6 +193,15 @@
 	//
 	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
 	Vendor_available *bool
+
+	// whether this module is capable of being loaded with other instance
+	// (possibly an older version) of the same module in the same process.
+	// Currently, a shared library that is a member of VNDK (vndk: {enabled: true})
+	// can be double loaded in a vendor process if the library is also a
+	// (direct and indirect) dependency of an LLNDK library. Such libraries must be
+	// explicitly marked as `double_loadable: true` by the owner, or the dependency
+	// from the LLNDK lib should be cut if the lib is not designed to be double loaded.
+	Double_loadable *bool
 }
 
 type UnusedProperties struct {
@@ -1127,6 +1136,34 @@
 	}
 }
 
+// Tests whether the dependent library is okay to be double loaded inside a single process.
+// If a library is a member of VNDK and at the same time dependencies of an LLNDK library,
+// it is subject to be double loaded. Such lib should be explicitly marked as double_loaded: true
+// or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
+func checkDoubleLoadableLibries(ctx android.ModuleContext, from *Module, to *Module) {
+	if _, ok := from.linker.(*libraryDecorator); !ok {
+		return
+	}
+
+	if inList(ctx.ModuleName(), llndkLibraries) ||
+		(from.useVndk() && Bool(from.VendorProperties.Double_loadable)) {
+		_, depIsLlndk := to.linker.(*llndkStubDecorator)
+		depIsVndkSp := false
+		if to.vndkdep != nil && to.vndkdep.isVndkSp() {
+			depIsVndkSp = true
+		}
+		depIsVndk := false
+		if to.vndkdep != nil && to.vndkdep.isVndk() {
+			depIsVndk = true
+		}
+		depIsDoubleLoadable := Bool(to.VendorProperties.Double_loadable)
+		if !depIsLlndk && !depIsVndkSp && !depIsDoubleLoadable && depIsVndk {
+			ctx.ModuleErrorf("links VNDK library %q that isn't double_loadable.",
+				ctx.OtherModuleName(to))
+		}
+	}
+}
+
 // Convert dependencies to paths.  Returns a PathDeps containing paths
 func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
 	var depPaths PathDeps
@@ -1225,6 +1262,7 @@
 			}
 
 			checkLinkType(ctx, c, ccDep, t)
+			checkDoubleLoadableLibries(ctx, c, ccDep)
 		}
 
 		var ptr *android.Paths
diff --git a/cmd/pom2mk/pom2mk.go b/cmd/pom2mk/pom2mk.go
index b4659f7..a635586 100644
--- a/cmd/pom2mk/pom2mk.go
+++ b/cmd/pom2mk/pom2mk.go
@@ -160,6 +160,10 @@
 // method are formatted as Make targets, e.g. run through MavenToMk rules.
 func (p Pom) MkDeps(typeExt string, scopes []string) []string {
 	var ret []string
+	if typeExt == "jar" {
+		// all top-level extra deps are assumed to be of type "jar" until we add syntax to specify other types
+		ret = append(ret, extraDeps[p.MkName()]...)
+	}
 	for _, d := range p.Dependencies {
 		if d.Type != typeExt || !InList(d.Scope, scopes) {
 			continue
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 0700487..a29f0ba 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -256,7 +256,9 @@
 func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
 	for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
 		for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
-			prefix := filepath.Join(dir, pkg)
+			// convert foo.bar.baz to foo/bar/baz
+			pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
+			prefix := filepath.Join(dir, pkgAsPath)
 			if _, found := whitelistPathPrefixes[prefix]; !found {
 				whitelistPathPrefixes[prefix] = true
 			}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 301ec61..13a9275 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -18,8 +18,11 @@
 	"android/soong/android"
 	"android/soong/genrule"
 	"fmt"
+	"io"
 	"path"
+	"sort"
 	"strings"
+	"sync"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -43,6 +46,10 @@
 	systemApiStubsTag = dependencyTag{name: "system"}
 )
 
+var (
+	javaSdkLibrariesLock sync.Mutex
+)
+
 // java_sdk_library is to make a Java library that implements optional platform APIs to apps.
 // It is actually a wrapper of several modules: 1) stubs library that clients are linked against
 // to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
@@ -62,6 +69,12 @@
 	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
 	})
+
+	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
+		javaSdkLibraries := javaSdkLibraries(ctx.Config())
+		sort.Strings(*javaSdkLibraries)
+		ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
+	})
 }
 
 type sdkLibraryProperties struct {
@@ -120,6 +133,20 @@
 	})
 }
 
+func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
+	// Create a phony module that installs the impl library, for the case when this lib is
+	// in PRODUCT_PACKAGES.
+	return android.AndroidMkData{
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
+			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
+		},
+	}
+}
+
 // Module name of the stubs library
 func (module *sdkLibrary) stubsName(forSystemApi bool) string {
 	stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
@@ -210,6 +237,9 @@
 			Unbundled_build struct {
 				Enabled *bool
 			}
+			Pdk struct {
+				Enabled *bool
+			}
 		}
 	}{}
 
@@ -219,6 +249,7 @@
 	props.Sdk_version = proptools.StringPtr(module.sdkVersion(forSystemApi))
 	// Unbundled apps will use the prebult one from /prebuilts/sdk
 	props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
+	props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
 
 	if module.SocSpecific() {
 		props.Soc_specific = proptools.BoolPtr(true)
@@ -281,17 +312,25 @@
 	props.Api_filename = proptools.StringPtr(currentApiFileName)
 	props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
 
-	// Includes the main framework source to ensure that doclava has access to the
-	// visibility information for the base classes of the mock classes. Without it
-	// otherwise hidden methods could be visible.
-	// TODO: remove the need for this
+	// Include the part of the framework source. This is required for the case when
+	// API class is extending from the framework class. In that case, doclava needs
+	// to know whether the base class is hidden or not. Since that information is
+	// encoded as @hide string in the comment, we need source files for the classes,
+	// not the compiled ones. Also there are rare cases where part of SDK library is
+	// implemented in the framework (e.g. org.apache.http.legacy). In that case,
+	// we need framework source to make API stubs, though the sources are not
+	// required to build the runtime library.
 	props.Srcs_lib = proptools.StringPtr("framework")
 	props.Srcs_lib_whitelist_dirs = []string{"core/java"}
-	props.Srcs_lib_whitelist_pkgs = []string{"android"}
-	// These libs are required by doclava to parse the sources from framework.
+	props.Srcs_lib_whitelist_pkgs = module.properties.Api_packages
+	// Add android.annotation package to give access to the framework-defined
+	// annotations such as SystemApi, NonNull, etc.
+	props.Srcs_lib_whitelist_pkgs = append(props.Srcs_lib_whitelist_pkgs, "android.annotation")
+	// These libs are required by doclava to parse the framework sources add via
+	// Src_lib and Src_lib_whitelist_* properties just above.
 	// If we don't add them to the classpath, errors messages are generated by doclava,
 	// though they don't break the build.
-	props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp")
+	props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
 
 	mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
 }
@@ -397,6 +436,12 @@
 	}
 }
 
+func javaSdkLibraries(config android.Config) *[]string {
+	return config.Once("javaSdkLibraries", func() interface{} {
+		return &[]string{}
+	}).(*[]string)
+}
+
 // For a java_sdk_library module, create internal modules for stubs, docs,
 // runtime libs and xml file. If requested, the stubs and docs are created twice
 // once for public API level and once for system API level
@@ -413,6 +458,12 @@
 		// for runtime
 		module.createXmlFile(mctx)
 		module.createImplLibrary(mctx)
+
+		// record java_sdk_library modules so that they are exported to make
+		javaSdkLibraries := javaSdkLibraries(mctx.Config())
+		javaSdkLibrariesLock.Lock()
+		defer javaSdkLibrariesLock.Unlock()
+		*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
 	}
 }