Merge "Make privileged java_library modules use uncompressed dex"
diff --git a/android/makevars.go b/android/makevars.go
index 3a7ec6e..366bb6b 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -22,6 +22,8 @@
 	"strconv"
 	"strings"
 
+	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -38,7 +40,21 @@
 type MakeVarsContext interface {
 	Config() Config
 	DeviceConfig() DeviceConfig
-	SingletonContext() SingletonContext
+	AddNinjaFileDeps(deps ...string)
+	Fs() pathtools.FileSystem
+
+	ModuleName(module blueprint.Module) string
+	ModuleDir(module blueprint.Module) string
+	ModuleSubDir(module blueprint.Module) string
+	ModuleType(module blueprint.Module) string
+	BlueprintFile(module blueprint.Module) string
+
+	ModuleErrorf(module blueprint.Module, format string, args ...interface{})
+	Errorf(format string, args ...interface{})
+	Failed() bool
+
+	VisitAllModules(visit func(Module))
+	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
 
 	// Verify the make variable matches the Soong version, fail the build
 	// if it does not. If the make variable is empty, just set it.
@@ -66,6 +82,8 @@
 	CheckRaw(name, value string)
 }
 
+var _ PathContext = MakeVarsContext(nil)
+
 type MakeVarsProvider func(ctx MakeVarsContext)
 
 func RegisterMakeVarsProvider(pctx PackageContext, provider MakeVarsProvider) {
@@ -92,8 +110,8 @@
 var makeVarsProviders []makeVarsProvider
 
 type makeVarsContext struct {
+	SingletonContext
 	config Config
-	ctx    SingletonContext
 	pctx   PackageContext
 	vars   []makeVarsVariable
 }
@@ -121,9 +139,8 @@
 	vars := []makeVarsVariable{}
 	for _, provider := range makeVarsProviders {
 		mctx := &makeVarsContext{
-			config: ctx.Config(),
-			ctx:    ctx,
-			pctx:   provider.pctx,
+			SingletonContext: ctx,
+			pctx:             provider.pctx,
 		}
 
 		provider.call(mctx)
@@ -229,22 +246,14 @@
 	return buf.Bytes()
 }
 
-func (c *makeVarsContext) Config() Config {
-	return c.config
-}
-
 func (c *makeVarsContext) DeviceConfig() DeviceConfig {
-	return DeviceConfig{c.config.deviceConfig}
-}
-
-func (c *makeVarsContext) SingletonContext() SingletonContext {
-	return c.ctx
+	return DeviceConfig{c.Config().deviceConfig}
 }
 
 var ninjaDescaper = strings.NewReplacer("$$", "$")
 
 func (c *makeVarsContext) Eval(ninjaStr string) (string, error) {
-	s, err := c.ctx.Eval(c.pctx, ninjaStr)
+	s, err := c.SingletonContext.Eval(c.pctx, ninjaStr)
 	if err != nil {
 		return "", err
 	}
@@ -265,7 +274,7 @@
 func (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool) {
 	value, err := c.Eval(ninjaStr)
 	if err != nil {
-		c.ctx.Errorf(err.Error())
+		c.SingletonContext.Errorf(err.Error())
 	}
 	c.addVariableRaw(name, value, strict, sort)
 }
diff --git a/android/paths.go b/android/paths.go
index 4b84c97..4b35fef 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -263,9 +263,9 @@
 }
 
 // PathsWithOptionalDefaultForModuleSrc returns Paths rooted from the module's
-// local source directory. If none are provided, use the default if it exists.
+// local source directory. If input is nil, use the default if it exists.  If input is empty, returns nil.
 func PathsWithOptionalDefaultForModuleSrc(ctx ModuleContext, input []string, def string) Paths {
-	if len(input) > 0 {
+	if input != nil {
 		return PathsForModuleSrc(ctx, input)
 	}
 	// Use Glob so that if the default doesn't exist, a dependency is added so that when it
diff --git a/android/singleton.go b/android/singleton.go
index f926435..05ec6b5 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -22,6 +22,7 @@
 // SingletonContext
 type SingletonContext interface {
 	Config() Config
+	DeviceConfig() DeviceConfig
 
 	ModuleName(module blueprint.Module) string
 	ModuleDir(module blueprint.Module) string
@@ -93,6 +94,10 @@
 	return s.SingletonContext.Config().(Config)
 }
 
+func (s singletonContextAdaptor) DeviceConfig() DeviceConfig {
+	return DeviceConfig{s.Config().deviceConfig}
+}
+
 func (s singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
 	s.SingletonContext.Variable(pctx.PackageContext, name, value)
 }
diff --git a/apex/apex.go b/apex/apex.go
index d25c256..092868e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -137,6 +137,7 @@
 	pctx.HostBinToolVariable("zipalign", "zipalign")
 
 	android.RegisterModuleType("apex", ApexBundleFactory)
+	android.RegisterModuleType("apex_defaults", defaultsFactory)
 
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("apex_deps", apexDepsMutator)
@@ -147,13 +148,18 @@
 // Mark the direct and transitive dependencies of apex bundles so that they
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
-	if _, ok := mctx.Module().(*apexBundle); ok {
+	if a, ok := mctx.Module().(*apexBundle); ok {
 		apexBundleName := mctx.ModuleName()
 		mctx.WalkDeps(func(child, parent android.Module) bool {
 			depName := mctx.OtherModuleName(child)
 			// If the parent is apexBundle, this child is directly depended.
 			_, directDep := parent.(*apexBundle)
-			android.UpdateApexDependency(apexBundleName, depName, directDep)
+			if a.installable() {
+				// TODO(b/123892969): Workaround for not having any way to annotate test-apexs
+				// non-installable apex's cannot be installed and so should not prevent libraries from being
+				// installed to the system.
+				android.UpdateApexDependency(apexBundleName, depName, directDep)
+			}
 
 			if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() {
 				am.BuildForApex(apexBundleName)
@@ -1098,3 +1104,31 @@
 	android.InitDefaultableModule(module)
 	return module
 }
+
+//
+// Defaults
+//
+type Defaults struct {
+	android.ModuleBase
+	android.DefaultsModuleBase
+}
+
+func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+}
+
+func defaultsFactory() android.Module {
+	return DefaultsFactory()
+}
+
+func DefaultsFactory(props ...interface{}) android.Module {
+	module := &Defaults{}
+
+	module.AddProperties(props...)
+	module.AddProperties(
+		&apexBundleProperties{},
+		&apexTargetBundleProperties{},
+	)
+
+	android.InitDefaultsModule(module)
+	return module
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 56ddd5f..6163d0f 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -33,6 +33,8 @@
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(ApexBundleFactory))
 	ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
+	ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 
 	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("apex_deps", apexDepsMutator)
@@ -201,8 +203,8 @@
 // Minimal test
 func TestBasicApex(t *testing.T) {
 	ctx := testApex(t, `
-		apex {
-			name: "myapex",
+		apex_defaults {
+			name: "myapex-defaults",
 			key: "myapex.key",
 			native_shared_libs: ["mylib"],
 			multilib: {
@@ -212,6 +214,11 @@
 			}
 		}
 
+		apex {
+			name: "myapex",
+			defaults: ["myapex-defaults"],
+		}
+
 		apex_key {
 			name: "myapex.key",
 			public_key: "testkey.avbpubkey",
diff --git a/cc/makevars.go b/cc/makevars.go
index d91735f..4a9ade2 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -100,7 +100,7 @@
 
 	// Filter vendor_public_library that are exported to make
 	exportedVendorPublicLibraries := []string{}
-	ctx.SingletonContext().VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModules(func(module android.Module) {
 		if ccModule, ok := module.(*Module); ok {
 			baseName := ccModule.BaseModuleName()
 			if inList(baseName, vendorPublicLibraries) && module.ExportedToMake() {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 1b09f88..3ae4452 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -53,6 +53,7 @@
 		"OpenMAXAL",
 		"OpenSLES",
 		"stdc++",
+		"sync",
 		"vulkan",
 		"z",
 	}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 6a3d579..330c5dd 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -172,7 +172,8 @@
 
 	stat := &status.Status{}
 	defer stat.Finish()
-	stat.AddOutput(terminal.NewStatusOutput(writer, ""))
+	stat.AddOutput(terminal.NewStatusOutput(writer, "",
+		build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD")))
 
 	var failures failureCount
 	stat.AddOutput(&failures)
@@ -389,7 +390,8 @@
 		Thread:  mpctx.Tracer.NewThread(product),
 		Status:  &status.Status{},
 	}}
-	ctx.Status.AddOutput(terminal.NewStatusOutput(ctx.Writer, ""))
+	ctx.Status.AddOutput(terminal.NewStatusOutput(ctx.Writer, "",
+		build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD")))
 
 	config := build.NewConfig(ctx, flag.Args()...)
 	config.Environment().Set("OUT_DIR", outDir)
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 0380368..d6999c5 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -78,7 +78,8 @@
 
 	stat := &status.Status{}
 	defer stat.Finish()
-	stat.AddOutput(terminal.NewStatusOutput(writer, os.Getenv("NINJA_STATUS")))
+	stat.AddOutput(terminal.NewStatusOutput(writer, os.Getenv("NINJA_STATUS"),
+		build.OsEnvironment().IsEnvTrue("ANDROID_QUIET_BUILD")))
 	stat.AddOutput(trace.StatusTracer())
 
 	build.SetupSignals(log, cancel, func() {
diff --git a/java/aar.go b/java/aar.go
index b01962a..0d38e9f 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -53,11 +53,13 @@
 	Aapt_include_all_resources *bool
 
 	// list of directories relative to the Blueprints file containing assets.
-	// Defaults to "assets"
+	// Defaults to ["assets"] if a directory called assets exists.  Set to []
+	// to disable the default.
 	Asset_dirs []string
 
 	// list of directories relative to the Blueprints file containing
-	// Android resources
+	// Android resources.  Defaults to ["res"] if a directory called res exists.
+	// Set to [] to disable the default.
 	Resource_dirs []string
 
 	// path to AndroidManifest.xml.  If unset, defaults to "AndroidManifest.xml".
diff --git a/java/app_test.go b/java/app_test.go
index 93d20d0..103f24b 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -106,6 +106,64 @@
 	}
 }
 
+func TestResourceDirs(t *testing.T) {
+	testCases := []struct {
+		name      string
+		prop      string
+		resources []string
+	}{
+		{
+			name:      "no resource_dirs",
+			prop:      "",
+			resources: []string{"res/res/values/strings.xml"},
+		},
+		{
+			name:      "resource_dirs",
+			prop:      `resource_dirs: ["res"]`,
+			resources: []string{"res/res/values/strings.xml"},
+		},
+		{
+			name:      "empty resource_dirs",
+			prop:      `resource_dirs: []`,
+			resources: nil,
+		},
+	}
+
+	fs := map[string][]byte{
+		"res/res/values/strings.xml": nil,
+	}
+
+	bp := `
+			android_app {
+				name: "foo",
+				%s
+			}
+		`
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+			config := testConfig(nil)
+			ctx := testContext(config, fmt.Sprintf(bp, testCase.prop), fs)
+			run(t, ctx, config)
+
+			module := ctx.ModuleForTests("foo", "android_common")
+			resourceList := module.MaybeOutput("aapt2/res.list")
+
+			var resources []string
+			if resourceList.Rule != nil {
+				for _, compiledResource := range resourceList.Inputs.Strings() {
+					resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
+				}
+			}
+
+			if !reflect.DeepEqual(resources, testCase.resources) {
+				t.Errorf("expected resource files %q, got %q",
+					testCase.resources, resources)
+			}
+		})
+	}
+}
+
 func TestEnforceRRO(t *testing.T) {
 	testCases := []struct {
 		name                       string
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 96de755..de1bcf5 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -283,7 +283,7 @@
 // Both paths are used to call dist-for-goals.
 func hiddenAPIMakeVars(ctx android.MakeVarsContext) {
 	if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
-		singletonPaths := ctx.Config().Get(hiddenAPISingletonPathsKey).(hiddenAPISingletonPathsStruct)
+		singletonPaths := hiddenAPISingletonPaths(ctx)
 		ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", singletonPaths.flags.String())
 		ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA", singletonPaths.metadata.String())
 	}
diff --git a/java/support_libraries.go b/java/support_libraries.go
index 320afae..5a72f41 100644
--- a/java/support_libraries.go
+++ b/java/support_libraries.go
@@ -28,9 +28,8 @@
 func supportLibrariesMakeVarsProvider(ctx android.MakeVarsContext) {
 	var supportAars, supportJars []string
 
-	sctx := ctx.SingletonContext()
-	sctx.VisitAllModules(func(module android.Module) {
-		dir := sctx.ModuleDir(module)
+	ctx.VisitAllModules(func(module android.Module) {
+		dir := ctx.ModuleDir(module)
 		switch {
 		case strings.HasPrefix(dir, "prebuilts/sdk/current/extras"),
 			dir == "prebuilts/sdk/current/androidx",
@@ -43,7 +42,7 @@
 			return
 		}
 
-		name := sctx.ModuleName(module)
+		name := ctx.ModuleName(module)
 		if strings.HasSuffix(name, "-nodeps") {
 			return
 		}
@@ -54,7 +53,7 @@
 		case *Library, *Import:
 			supportJars = append(supportJars, name)
 		default:
-			sctx.ModuleErrorf(module, "unknown module type %t", module)
+			ctx.ModuleErrorf(module, "unknown module type %t", module)
 		}
 	})
 
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 98bb1c5..d644f5f 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -214,11 +214,13 @@
 		ctx.Fatalln("Error dumping make vars:", err)
 	}
 
+	env := config.Environment()
 	// Print the banner like make does
-	ctx.Writer.Print(Banner(make_vars))
+	if !env.IsEnvTrue("ANDROID_QUIET_BUILD") {
+		ctx.Writer.Print(Banner(make_vars))
+	}
 
 	// Populate the environment
-	env := config.Environment()
 	for _, name := range exportEnvVars {
 		if make_vars[name] == "" {
 			env.Unset(name)
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index c8eb382..2445c5b 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -27,6 +27,7 @@
 	format string
 
 	start time.Time
+	quiet bool
 }
 
 // NewStatusOutput returns a StatusOutput that represents the
@@ -35,12 +36,13 @@
 //
 // statusFormat takes nearly all the same options as NINJA_STATUS.
 // %c is currently unsupported.
-func NewStatusOutput(w Writer, statusFormat string) status.StatusOutput {
+func NewStatusOutput(w Writer, statusFormat string, quietBuild bool) status.StatusOutput {
 	return &statusOutput{
 		writer: w,
 		format: statusFormat,
 
 		start: time.Now(),
+		quiet: quietBuild,
 	}
 }
 
@@ -76,13 +78,12 @@
 	progress := s.progress(counts) + str
 
 	if result.Error != nil {
-		hasCommand := ""
-		if result.Command != "" {
-			hasCommand = "\n"
+		targets := strings.Join(result.Outputs, " ")
+		if s.quiet || result.Command == "" {
+			s.writer.StatusAndMessage(progress, fmt.Sprintf("FAILED: %s\n%s", targets, result.Output))
+		} else {
+			s.writer.StatusAndMessage(progress, fmt.Sprintf("FAILED: %s\n%s\n%s", targets, result.Command, result.Output))
 		}
-
-		s.writer.StatusAndMessage(progress, fmt.Sprintf("FAILED: %s\n%s%s%s",
-			strings.Join(result.Outputs, " "), result.Command, hasCommand, result.Output))
 	} else if result.Output != "" {
 		s.writer.StatusAndMessage(progress, result.Output)
 	} else {