Merge "Prepare kzip script to support superproject sha as an environment variable"
diff --git a/cc/test.go b/cc/test.go
index 9b77e45..d4c23d7 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -46,6 +46,14 @@
 
 	// If the test is a hostside(no device required) unittest that shall be run during presubmit check.
 	Unit_test *bool
+
+	// Add ShippingApiLevelModuleController to auto generated test config. If the device properties
+	// for the shipping api level is less than the test_min_api_level, skip this module.
+	Test_min_api_level *int64
+
+	// Add MinApiLevelModuleController with ro.vndk.version property. If ro.vndk.version has an
+	// integer value and the value is less than the test_min_vndk_version, skip this module.
+	Test_min_vndk_version *int64
 }
 
 type TestBinaryProperties struct {
@@ -89,6 +97,7 @@
 
 	// Add ShippingApiLevelModuleController to auto generated test config. If the device properties
 	// for the shipping api level is less than the test_min_api_level, skip this module.
+	// Deprecated (b/187258404). Use test_options.test_min_api_level instead.
 	Test_min_api_level *int64
 
 	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
@@ -395,11 +404,22 @@
 	for _, tag := range test.Properties.Test_options.Test_suite_tag {
 		configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag})
 	}
-	if test.Properties.Test_min_api_level != nil {
+	if test.Properties.Test_options.Test_min_api_level != nil {
+		var options []tradefed.Option
+		options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Test_min_api_level), 10)})
+		configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
+	} else if test.Properties.Test_min_api_level != nil {
+		// TODO: (b/187258404) Remove test.Properties.Test_min_api_level
 		var options []tradefed.Option
 		options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_min_api_level), 10)})
 		configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
 	}
+	if test.Properties.Test_options.Test_min_vndk_version != nil {
+		var options []tradefed.Option
+		options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Test_min_vndk_version), 10)})
+		options = append(options, tradefed.Option{Name: "api-level-prop", Value: "ro.vndk.version"})
+		configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options})
+	}
 
 	test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
 		test.Properties.Test_config_template, test.Properties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 7397919..24492d4 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -49,7 +49,7 @@
 
 	ArtApexJars android.ConfiguredJarList // modules for jars that are in the ART APEX
 
-	SystemServerJars          []string                  // jars that form the system server
+	SystemServerJars          android.ConfiguredJarList // jars that form the system server
 	SystemServerApps          []string                  // apps that are loaded into system server
 	UpdatableSystemServerJars android.ConfiguredJarList // jars within apex that are loaded into system server
 	SpeedApps                 []string                  // apps that should be speed optimized
@@ -604,7 +604,7 @@
 		BootJars:                           android.EmptyConfiguredJarList(),
 		UpdatableBootJars:                  android.EmptyConfiguredJarList(),
 		ArtApexJars:                        android.EmptyConfiguredJarList(),
-		SystemServerJars:                   nil,
+		SystemServerJars:                   android.EmptyConfiguredJarList(),
 		SystemServerApps:                   nil,
 		UpdatableSystemServerJars:          android.EmptyConfiguredJarList(),
 		SpeedApps:                          nil,
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 628197c..c9a80f8 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -120,7 +120,7 @@
 	// /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
 	// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
 	if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
-		!contains(global.SystemServerJars, module.Name) && !module.PreoptExtractedApk {
+		!global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk {
 		return true
 	}
 
@@ -362,7 +362,7 @@
 
 	if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
 		var compilerFilter string
-		if contains(global.SystemServerJars, module.Name) {
+		if global.SystemServerJars.ContainsJar(module.Name) {
 			// Jars of system server, use the product option if it is set, speed otherwise.
 			if global.SystemServerCompilerFilter != "" {
 				compilerFilter = global.SystemServerCompilerFilter
@@ -416,7 +416,7 @@
 
 	// PRODUCT_SYSTEM_SERVER_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
 	// PRODUCT_OTHER_JAVA_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
-	if contains(global.SystemServerJars, module.Name) {
+	if global.SystemServerJars.ContainsJar(module.Name) {
 		if global.AlwaysSystemServerDebugInfo {
 			debugInfo = true
 		} else if global.NeverSystemServerDebugInfo {
@@ -524,7 +524,7 @@
 // from java subpackage to dexpreopt.
 func NonUpdatableSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
 	return ctx.Config().Once(nonUpdatableSystemServerJarsKey, func() interface{} {
-		return android.RemoveListFromList(global.SystemServerJars, global.UpdatableSystemServerJars.CopyOfJars())
+		return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.UpdatableSystemServerJars.CopyOfJars())
 	}).([]string)
 }
 
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index d497460..460cc3e 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -81,7 +81,7 @@
 	maxSdkVersion int32
 }
 
-func (c *ClasspathFragmentBase) generateAndroidBuildActions(ctx android.ModuleContext) {
+func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
 	outputFilename := ctx.ModuleName() + ".pb"
 	c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
 	c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
@@ -137,7 +137,7 @@
 	return
 }
 
-func (c *ClasspathFragmentBase) getAndroidMkEntries() []android.AndroidMkEntries {
+func (c *ClasspathFragmentBase) androidMkEntries() []android.AndroidMkEntries {
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "ETC",
 		OutputFile: android.OptionalPathForPath(c.outputFilepath),
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0020a2d..3113eb3 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -150,7 +150,7 @@
 
 	global := dexpreopt.GetGlobalConfig(ctx)
 
-	isSystemServerJar := inList(ctx.ModuleName(), global.SystemServerJars)
+	isSystemServerJar := global.SystemServerJars.ContainsJar(ctx.ModuleName())
 
 	bootImage := defaultBootImageConfig(ctx)
 	if global.UseArtImage {
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 0ab6502..72b61e3 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -39,10 +39,9 @@
 		// 2) The jars that are from an updatable apex.
 		systemServerClasspathLocations = append(systemServerClasspathLocations,
 			global.UpdatableSystemServerJars.DevicePaths(ctx.Config(), android.Android)...)
-		if len(systemServerClasspathLocations) != len(global.SystemServerJars)+global.UpdatableSystemServerJars.Len() {
-			panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d",
-				len(systemServerClasspathLocations),
-				len(global.SystemServerJars)+global.UpdatableSystemServerJars.Len()))
+
+		if expectedLen := global.SystemServerJars.Len() + global.UpdatableSystemServerJars.Len(); expectedLen != len(systemServerClasspathLocations) {
+			panic(fmt.Errorf("wrong number of system server jars, got %d, expected %d", len(systemServerClasspathLocations), expectedLen))
 		}
 		return systemServerClasspathLocations
 	})
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 3a59822..1acb9f4 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -87,7 +87,7 @@
 		OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV),
 		Include:    "$(BUILD_PHONY_PACKAGE)",
 	})
-	entries = append(entries, b.classpathFragmentBase().getAndroidMkEntries()...)
+	entries = append(entries, b.classpathFragmentBase().androidMkEntries()...)
 	return
 }
 
@@ -167,7 +167,7 @@
 }
 
 func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	b.classpathFragmentBase().generateAndroidBuildActions(ctx)
+	b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx)
 
 	// Gather all the dependencies from the art, updatable and non-updatable boot jars.
 	artModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathArtBootJarDepTag)
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 95a4930..2f56de6 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -307,8 +307,8 @@
 
 		// Generate the snapshot from the member info.
 		p := s.buildSnapshot(ctx, sdkVariants)
-		s.snapshotFile = android.OptionalPathForPath(p)
-		ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), s.Name()+"-current.zip", p)
+		zip := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), p.Base(), p)
+		s.snapshotFile = android.OptionalPathForPath(zip)
 	}
 }
 
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index b7da95c..e9129e0 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -464,3 +464,65 @@
     "struct-0" has value "should-be-but-is-not-common0"
     "struct-1" has value "should-be-but-is-not-common1"`, err)
 }
+
+// Ensure that sdk snapshot related environment variables work correctly.
+func TestSnapshot_EnvConfiguration(t *testing.T) {
+	bp := `
+		sdk {
+			name: "mysdk",
+			java_header_libs: ["myjavalib"],
+		}
+
+		java_library {
+			name: "myjavalib",
+			srcs: ["Test.java"],
+			system_modules: "none",
+			sdk_version: "none",
+			compile_dex: true,
+			host_supported: true,
+		}
+	`
+	preparer := android.GroupFixturePreparers(
+		prepareForSdkTestWithJava,
+		android.FixtureWithRootAndroidBp(bp),
+	)
+
+	checkZipFile := func(t *testing.T, result *android.TestResult, expected string) {
+		zipRule := result.ModuleForTests("mysdk", "common_os").Rule("SnapshotZipFiles")
+		android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String())
+	}
+
+	t.Run("no env variables", func(t *testing.T) {
+		result := preparer.RunTest(t)
+
+		checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
+
+		CheckSnapshot(t, result, "mysdk", "",
+			checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+    name: "mysdk_myjavalib@current",
+    sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+    name: "myjavalib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java/myjavalib.jar"],
+}
+
+sdk_snapshot {
+    name: "mysdk@current",
+    visibility: ["//visibility:public"],
+    java_header_libs: ["mysdk_myjavalib@current"],
+}
+			`),
+		)
+	})
+}