Merge "Allow reading zipfile list from a file."
diff --git a/Android.bp b/Android.bp
index 62b0fd4..4e44a0d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -282,6 +282,7 @@
         "java/jdeps.go",
         "java/java_resources.go",
         "java/kotlin.go",
+        "java/platform_compat_config.go",
         "java/plugin.go",
         "java/prebuilt_apis.go",
         "java/proto.go",
diff --git a/android/neverallow.go b/android/neverallow.go
index 23b6454..8355bb3 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -175,6 +175,8 @@
 	dir := ctx.ModuleDir() + "/"
 	properties := m.GetProperties()
 
+	osClass := ctx.Module().Target().Os.Class
+
 	for _, r := range neverallows {
 		n := r.(*rule)
 		if !n.appliesToPath(dir) {
@@ -189,6 +191,14 @@
 			continue
 		}
 
+		if !n.appliesToOsClass(osClass) {
+			continue
+		}
+
+		if !n.appliesToDirectDeps(ctx) {
+			continue
+		}
+
 		ctx.ModuleErrorf("violates " + n.String())
 	}
 }
@@ -246,6 +256,10 @@
 
 	NotIn(path ...string) Rule
 
+	InDirectDeps(deps ...string) Rule
+
+	WithOsClass(osClasses ...OsClass) Rule
+
 	ModuleType(types ...string) Rule
 
 	NotModuleType(types ...string) Rule
@@ -268,6 +282,10 @@
 	paths       []string
 	unlessPaths []string
 
+	directDeps map[string]bool
+
+	osClasses []OsClass
+
 	moduleTypes       []string
 	unlessModuleTypes []string
 
@@ -277,7 +295,7 @@
 
 // Create a new NeverAllow rule.
 func NeverAllow() Rule {
-	return &rule{}
+	return &rule{directDeps: make(map[string]bool)}
 }
 
 func (r *rule) In(path ...string) Rule {
@@ -290,6 +308,18 @@
 	return r
 }
 
+func (r *rule) InDirectDeps(deps ...string) Rule {
+	for _, d := range deps {
+		r.directDeps[d] = true
+	}
+	return r
+}
+
+func (r *rule) WithOsClass(osClasses ...OsClass) Rule {
+	r.osClasses = append(r.osClasses, osClasses...)
+	return r
+}
+
 func (r *rule) ModuleType(types ...string) Rule {
 	r.moduleTypes = append(r.moduleTypes, types...)
 	return r
@@ -356,6 +386,12 @@
 	for _, v := range r.unlessProps {
 		s += " -" + strings.Join(v.fields, ".") + v.matcher.String()
 	}
+	for k := range r.directDeps {
+		s += " deps:" + k
+	}
+	for _, v := range r.osClasses {
+		s += " os:" + v.String()
+	}
 	if len(r.reason) != 0 {
 		s += " which is restricted because " + r.reason
 	}
@@ -368,6 +404,36 @@
 	return includePath && !excludePath
 }
 
+func (r *rule) appliesToDirectDeps(ctx BottomUpMutatorContext) bool {
+	if len(r.directDeps) == 0 {
+		return true
+	}
+
+	matches := false
+	ctx.VisitDirectDeps(func(m Module) {
+		if !matches {
+			name := ctx.OtherModuleName(m)
+			matches = r.directDeps[name]
+		}
+	})
+
+	return matches
+}
+
+func (r *rule) appliesToOsClass(osClass OsClass) bool {
+	if len(r.osClasses) == 0 {
+		return true
+	}
+
+	for _, c := range r.osClasses {
+		if c == osClass {
+			return true
+		}
+	}
+
+	return false
+}
+
 func (r *rule) appliesToModuleType(moduleType string) bool {
 	return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes)
 }
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 02b4362..920b9a5 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -16,13 +16,43 @@
 
 import (
 	"testing"
+
+	"github.com/google/blueprint"
 )
 
+func init() {
+	// Add extra rules needed for testing.
+	AddNeverAllowRules(
+		NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
+	)
+}
+
 var neverallowTests = []struct {
 	name          string
 	fs            map[string][]byte
 	expectedError string
 }{
+	// Test General Functionality
+
+	// in direct deps tests
+	{
+		name: "not_allowed_in_direct_deps",
+		fs: map[string][]byte{
+			"top/Blueprints": []byte(`
+				cc_library {
+					name: "not_allowed_in_direct_deps",
+				}`),
+			"other/Blueprints": []byte(`
+				cc_library {
+					name: "libother",
+					static_libs: ["not_allowed_in_direct_deps"],
+				}`),
+		},
+		expectedError: `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
+	},
+
+	// Test specific rules
+
 	// include_dir rule tests
 	{
 		name: "include_dir not allowed to reference art",
@@ -242,6 +272,7 @@
 type mockCcLibraryProperties struct {
 	Include_dirs     []string
 	Vendor_available *bool
+	Static_libs      []string
 
 	Vndk struct {
 		Enabled                *bool
@@ -272,6 +303,19 @@
 	return m
 }
 
+type neverallowTestDependencyTag struct {
+	blueprint.BaseDependencyTag
+	name string
+}
+
+var staticDepTag = neverallowTestDependencyTag{name: "static"}
+
+func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
+	for _, lib := range c.properties.Static_libs {
+		ctx.AddDependency(ctx.Module(), staticDepTag, lib)
+	}
+}
+
 func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
 }
 
diff --git a/apex/TEST_MAPPING b/apex/TEST_MAPPING
new file mode 100644
index 0000000..d0223d1
--- /dev/null
+++ b/apex/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "system/apex/apexd"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cc/cc.go b/cc/cc.go
index 54f21aa..2bde2d3 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -267,7 +267,7 @@
 	isVndkSp() bool
 	isVndkExt() bool
 	inRecovery() bool
-	shouldCreateVndkSourceAbiDump(config android.Config) bool
+	shouldCreateSourceAbiDump() bool
 	selectedStl() string
 	baseModuleName() string
 	getVndkExtendsModuleName() string
@@ -789,7 +789,7 @@
 }
 
 // Check whether ABI dumps should be created for this module.
-func (ctx *moduleContextImpl) shouldCreateVndkSourceAbiDump(config android.Config) bool {
+func (ctx *moduleContextImpl) shouldCreateSourceAbiDump() bool {
 	if ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
 		return false
 	}
@@ -815,18 +815,7 @@
 		// Stubs do not need ABI dumps.
 		return false
 	}
-	if ctx.isNdk() {
-		return true
-	}
-	if ctx.isLlndkPublic(config) {
-		return true
-	}
-	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(config) {
-		// Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext and this is not
-		// VNDK-private.
-		return true
-	}
-	return false
+	return true
 }
 
 func (ctx *moduleContextImpl) selectedStl() string {
diff --git a/cc/config/global.go b/cc/config/global.go
index a27246e..9ce6896 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -150,8 +150,22 @@
 	pctx.StaticVariable("HostGlobalLdflags", strings.Join(hostGlobalLdflags, " "))
 	pctx.StaticVariable("HostGlobalLldflags", strings.Join(hostGlobalLldflags, " "))
 
-	pctx.StaticVariable("CommonClangGlobalCflags",
-		strings.Join(append(ClangFilterUnknownCflags(commonGlobalCflags), "${ClangExtraCflags}"), " "))
+	pctx.VariableFunc("CommonClangGlobalCflags", func(ctx android.PackageVarContext) string {
+		flags := ClangFilterUnknownCflags(commonGlobalCflags)
+		flags = append(flags, "${ClangExtraCflags}")
+
+		// http://b/131390872
+		// Automatically initialize any uninitialized stack variables.
+		// Prefer zero-init if both options are set.
+		if ctx.Config().IsEnvTrue("AUTO_ZERO_INITIALIZE") {
+			flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
+		} else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") {
+			flags = append(flags, "-ftrivial-auto-var-init=pattern")
+		}
+
+		return strings.Join(flags, " ")
+	})
+
 	pctx.VariableFunc("DeviceClangGlobalCflags", func(ctx android.PackageVarContext) string {
 		if ctx.Config().Fuchsia() {
 			return strings.Join(ClangFilterUnknownCflags(deviceGlobalCflags), " ")
diff --git a/cc/library.go b/cc/library.go
index 2b7c9a1..b193ab7 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -432,11 +432,25 @@
 	return flags
 }
 
-func (library *libraryDecorator) shouldCreateVndkSourceAbiDump(ctx ModuleContext) bool {
+func (library *libraryDecorator) shouldCreateSourceAbiDump(ctx ModuleContext) bool {
+	if !ctx.shouldCreateSourceAbiDump() {
+		return false
+	}
 	if library.Properties.Header_abi_checker.Enabled != nil {
 		return Bool(library.Properties.Header_abi_checker.Enabled)
 	}
-	return ctx.shouldCreateVndkSourceAbiDump(ctx.Config())
+	if ctx.isNdk() {
+		return true
+	}
+	if ctx.isLlndkPublic(ctx.Config()) {
+		return true
+	}
+	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) {
+		// Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext, and not
+		// VNDK-private.
+		return true
+	}
+	return false
 }
 
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -458,7 +472,7 @@
 		}
 		return Objects{}
 	}
-	if library.shouldCreateVndkSourceAbiDump(ctx) || library.sabi.Properties.CreateSAbiDumps {
+	if library.shouldCreateSourceAbiDump(ctx) || library.sabi.Properties.CreateSAbiDumps {
 		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
 		var SourceAbiFlags []string
 		for _, dir := range exportIncludeDirs.Strings() {
@@ -822,7 +836,7 @@
 }
 
 func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
-	if library.shouldCreateVndkSourceAbiDump(ctx) {
+	if library.shouldCreateSourceAbiDump(ctx) {
 		vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
 		if ver := ctx.DeviceConfig().VndkVersion(); ver != "" && ver != "current" {
 			vndkVersion = ver
diff --git a/cc/linker.go b/cc/linker.go
index daacec1..962fcce 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -125,6 +125,10 @@
 			// variant of the C/C++ module.
 			Shared_libs []string
 
+			// list of static libs that only should be used to build the recovery
+			// variant of the C/C++ module.
+			Static_libs []string
+
 			// list of shared libs that should not be used to build
 			// the recovery variant of the C/C++ module.
 			Exclude_shared_libs []string
@@ -211,6 +215,7 @@
 		deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Recovery.Shared_libs...)
 		deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs)
 		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs)
+		deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Recovery.Static_libs...)
 		deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
 		deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Recovery.Exclude_header_libs)
 		deps.ReexportHeaderLibHeaders = removeListFromList(deps.ReexportHeaderLibHeaders, linker.Properties.Target.Recovery.Exclude_header_libs)
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
new file mode 100644
index 0000000..792edf3
--- /dev/null
+++ b/java/platform_compat_config.go
@@ -0,0 +1,92 @@
+// 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.
+
+package java
+
+import (
+	"android/soong/android"
+)
+
+func init() {
+	android.RegisterModuleType("platform_compat_config", platformCompatConfigFactory)
+}
+
+type platformCompatConfigProperties struct {
+	Src    *string `android:"path"`
+	Prefix *string
+}
+
+type platformCompatConfig struct {
+	android.ModuleBase
+
+	properties     platformCompatConfigProperties
+	installDirPath android.OutputPath
+	configFile     android.OutputPath
+}
+
+func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	rule := android.NewRuleBuilder()
+
+	configFileName := String(p.properties.Prefix) + "_platform_compat_config.xml"
+	p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
+	path := android.PathForModuleSrc(ctx, String(p.properties.Src))
+
+	// Use the empty config if the compat config file idoesn't exist (can happen if @ChangeId
+	// annotation is not used).
+	emptyConfig := `<?xml version="1.0" encoding="UTF-8" standalone="no"?><config/>`
+	configPath := `compat/compat_config.xml`
+
+	rule.Command().
+		Text(`unzip`).
+		Flag(`-l`).
+		Input(path).
+		Text(`| grep`).
+		Flag(`-q`).
+		Text(configPath).
+		Text(`; if [ "$?" = "0" ] ; then`).
+		Text(`unzip`).
+		Flag(`-qp`).
+		Input(path).
+		Text(configPath).
+		Text(`>`).
+		Output(p.configFile).
+		Text(`; else echo '`).
+		Text(emptyConfig).
+		Text(`' >`).
+		Output(p.configFile).
+		Text(`; fi`)
+
+	p.installDirPath = android.PathForModuleInstall(ctx, "etc", "sysconfig")
+	rule.Build(pctx, ctx, configFileName, "Extract compat/compat_config.xml and install it")
+
+}
+
+func (p *platformCompatConfig) AndroidMkEntries() android.AndroidMkEntries {
+	return android.AndroidMkEntries{
+		Class:      "ETC",
+		OutputFile: android.OptionalPathForPath(p.configFile),
+		Include:    "$(BUILD_PREBUILT)",
+		AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+			entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
+			entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
+		},
+	}
+}
+
+func platformCompatConfigFactory() android.Module {
+	module := &platformCompatConfig{}
+	module.AddProperties(&module.properties)
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	return module
+}