Merge "release_config: better default map paths" into main
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index 8e516b4..f3e9599 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -22,6 +22,7 @@
 	"github.com/google/blueprint/proptools"
 
 	"fmt"
+	"strconv"
 	"strings"
 )
 
@@ -152,6 +153,7 @@
 		Args: map[string]string{
 			"gendir": this.generatedDir.String(),
 			"mode":   mode,
+			"debug":  strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorageCc()),
 		},
 	})
 
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 73a8951..6182e14 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -49,11 +49,12 @@
 				` && ${aconfig} create-cpp-lib` +
 				`    --mode ${mode}` +
 				`    --cache ${in}` +
-				`    --out ${gendir}`,
+				`    --out ${gendir}` +
+				`    --allow-instrumentation ${debug}`,
 			CommandDeps: []string{
 				"$aconfig",
 			},
-		}, "gendir", "mode")
+		}, "gendir", "mode", "debug")
 
 	// For rust_aconfig_library: Generate Rust library
 	rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
diff --git a/android/config.go b/android/config.go
index 75d135f..b60eb5c 100644
--- a/android/config.go
+++ b/android/config.go
@@ -229,6 +229,11 @@
 	return c.config.productVariables.GetBuildFlagBool("RELEASE_NDK_ABI_MONITORED")
 }
 
+// Enable read flag from new storage, for C/C++
+func (c Config) ReleaseReadFromNewStorageCc() bool {
+	return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE_CC")
+}
+
 func (c Config) ReleaseHiddenApiExportableStubs() bool {
 	return c.config.productVariables.GetBuildFlagBool("RELEASE_HIDDEN_API_EXPORTABLE_STUBS") ||
 		Bool(c.config.productVariables.HiddenapiExportableStubs)
diff --git a/android/module.go b/android/module.go
index 5fe379c..effca03 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2142,13 +2142,13 @@
 func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
 	ctx := e.ctx
 	m := e.m
-	switch condition.FunctionName {
+	switch condition.FunctionName() {
 	case "release_variable":
-		if len(condition.Args) != 1 {
-			ctx.OtherModulePropertyErrorf(m, property, "release_variable requires 1 argument, found %d", len(condition.Args))
+		if condition.NumArgs() != 1 {
+			ctx.OtherModulePropertyErrorf(m, property, "release_variable requires 1 argument, found %d", condition.NumArgs())
 			return proptools.ConfigurableValueUndefined()
 		}
-		if v, ok := ctx.Config().productVariables.BuildFlags[condition.Args[0]]; ok {
+		if v, ok := ctx.Config().productVariables.BuildFlags[condition.Arg(0)]; ok {
 			return proptools.ConfigurableValueString(v)
 		}
 		return proptools.ConfigurableValueUndefined()
@@ -2157,12 +2157,12 @@
 		ctx.OtherModulePropertyErrorf(m, property, "TODO(b/323382414): Product variables are not yet supported in selects")
 		return proptools.ConfigurableValueUndefined()
 	case "soong_config_variable":
-		if len(condition.Args) != 2 {
-			ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", len(condition.Args))
+		if condition.NumArgs() != 2 {
+			ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", condition.NumArgs())
 			return proptools.ConfigurableValueUndefined()
 		}
-		namespace := condition.Args[0]
-		variable := condition.Args[1]
+		namespace := condition.Arg(0)
+		variable := condition.Arg(1)
 		if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
 			if v, ok := n[variable]; ok {
 				return proptools.ConfigurableValueString(v)
@@ -2170,8 +2170,8 @@
 		}
 		return proptools.ConfigurableValueUndefined()
 	case "arch":
-		if len(condition.Args) != 0 {
-			ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", len(condition.Args))
+		if condition.NumArgs() != 0 {
+			ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", condition.NumArgs())
 			return proptools.ConfigurableValueUndefined()
 		}
 		if !m.base().ArchReady() {
@@ -2180,8 +2180,8 @@
 		}
 		return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
 	case "os":
-		if len(condition.Args) != 0 {
-			ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", len(condition.Args))
+		if condition.NumArgs() != 0 {
+			ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", condition.NumArgs())
 			return proptools.ConfigurableValueUndefined()
 		}
 		// the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
@@ -2194,8 +2194,8 @@
 		// We currently don't have any other boolean variables (we should add support for typing
 		// the soong config variables), so add this fake one for testing the boolean select
 		// functionality.
-		if len(condition.Args) != 0 {
-			ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", len(condition.Args))
+		if condition.NumArgs() != 0 {
+			ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", condition.NumArgs())
 			return proptools.ConfigurableValueUndefined()
 		}
 
diff --git a/android/selects_test.go b/android/selects_test.go
index f912ce6..8563285 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -28,6 +28,7 @@
 		name          string
 		bp            string
 		provider      selectsTestProvider
+		providers     map[string]selectsTestProvider
 		vendorVars    map[string]map[string]string
 		expectedError string
 	}{
@@ -411,6 +412,42 @@
 			},
 		},
 		{
+			name: "defaults applied to multiple modules",
+			bp: `
+			my_module_type {
+				name: "foo2",
+				defaults: ["bar"],
+				my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+					"a": ["a1"],
+					default: ["b1"],
+				}),
+			}
+			my_module_type {
+				name: "foo",
+				defaults: ["bar"],
+				my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+					"a": ["a1"],
+					default: ["b1"],
+				}),
+			}
+			my_defaults {
+				name: "bar",
+				my_string_list: select(soong_config_variable("my_namespace", "my_variable2"), {
+					"a": ["a2"],
+					default: ["b2"],
+				}),
+			}
+			`,
+			providers: map[string]selectsTestProvider{
+				"foo": {
+					my_string_list: &[]string{"b2", "b1"},
+				},
+				"foo2": {
+					my_string_list: &[]string{"b2", "b1"},
+				},
+			},
+		},
+		{
 			name: "Replacing string list",
 			bp: `
 			my_module_type {
@@ -617,10 +654,19 @@
 			result := fixtures.RunTestWithBp(t, tc.bp)
 
 			if tc.expectedError == "" {
-				m := result.ModuleForTests("foo", "android_arm64_armv8-a")
-				p, _ := OtherModuleProvider(result.testContext.OtherModuleProviderAdaptor(), m.Module(), selectsTestProviderKey)
-				if !reflect.DeepEqual(p, tc.provider) {
-					t.Errorf("Expected:\n  %q\ngot:\n  %q", tc.provider.String(), p.String())
+				if len(tc.providers) == 0 {
+					tc.providers = map[string]selectsTestProvider{
+						"foo": tc.provider,
+					}
+				}
+
+				for moduleName := range tc.providers {
+					expected := tc.providers[moduleName]
+					m := result.ModuleForTests(moduleName, "android_arm64_armv8-a")
+					p, _ := OtherModuleProvider(result.testContext.OtherModuleProviderAdaptor(), m.Module(), selectsTestProviderKey)
+					if !reflect.DeepEqual(p, expected) {
+						t.Errorf("Expected:\n  %q\ngot:\n  %q", expected.String(), p.String())
+					}
 				}
 			}
 		})
diff --git a/java/droidstubs.go b/java/droidstubs.go
index ffd3caf..08caf91 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -614,11 +614,36 @@
 
 	filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
 
+	// TODO: Avoid the duplication of API surfaces, reuse apiScope.
+	// Add all relevant --android-jar-pattern patterns for Metalava.
+	// When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
+	// an actual file present on disk (in the order the patterns were passed). For system APIs for
+	// privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
+	// for older releases. Similarly, module-lib falls back to system API.
+	var sdkDirs []string
+	switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
+	case "system-server":
+		sdkDirs = []string{"system-server", "module-lib", "system", "public"}
+	case "module-lib":
+		sdkDirs = []string{"module-lib", "system", "public"}
+	case "system":
+		sdkDirs = []string{"system", "public"}
+	case "public":
+		sdkDirs = []string{"public"}
+	default:
+		ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
+		return
+	}
+
+	// Use the first item in the sdkDirs array as that is the sdk type for the target API levels
+	// being generated but has the advantage over `Api_levels_sdk_type` as it has been validated.
+	extensionsPattern := fmt.Sprintf(`/extensions/[0-9]+/%s/.*\.jar`, sdkDirs[0])
+
 	var dirs []string
 	var extensions_dir string
 	ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
 		if t, ok := m.(*ExportedDroiddocDir); ok {
-			extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
+			extRegex := regexp.MustCompile(t.dir.String() + extensionsPattern)
 
 			// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
 			// ideally this should be read from prebuiltApis.properties.Extensions_*
@@ -650,26 +675,6 @@
 		}
 	})
 
-	// Add all relevant --android-jar-pattern patterns for Metalava.
-	// When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
-	// an actual file present on disk (in the order the patterns were passed). For system APIs for
-	// privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
-	// for older releases. Similarly, module-lib falls back to system API.
-	var sdkDirs []string
-	switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
-	case "system-server":
-		sdkDirs = []string{"system-server", "module-lib", "system", "public"}
-	case "module-lib":
-		sdkDirs = []string{"module-lib", "system", "public"}
-	case "system":
-		sdkDirs = []string{"system", "public"}
-	case "public":
-		sdkDirs = []string{"public"}
-	default:
-		ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
-		return
-	}
-
 	for _, sdkDir := range sdkDirs {
 		for _, dir := range dirs {
 			cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
diff --git a/python/scripts/precompile_python.py b/python/scripts/precompile_python.py
index 07b8fe9..b3cf950 100644
--- a/python/scripts/precompile_python.py
+++ b/python/scripts/precompile_python.py
@@ -30,6 +30,7 @@
     # Date was chosen to be the same as
     # https://cs.android.com/android/platform/superproject/main/+/main:build/soong/jar/jar.go;l=36;drc=2863e4535eb65e15f955dc8ed48fa99b1d2a1db5
     info = zipfile.ZipInfo(filename=name, date_time=(2008, 1, 1, 0, 0, 0))
+    info.compress_type = zipfile.ZIP_DEFLATED
 
     if not info.filename.endswith('.py'):
         outzip.writestr(info, infile.read())