Flag to control if generated SDK prebuilts are preferred.

This is needed because:
- the SDK prebuilt drop is being automated, including the Android.bp
- We want to control the prefer flag on a per-module level

It augments the existing SOONG_SDK_SNAPSHOT_PREFER which now overrides
this new flag when set to true.

Bug: 188427719
Test: m nothing
Change-Id: Ieb5ab9fab53a34c615345b7a9d19cadf713eec26
diff --git a/sdk/sdk.go b/sdk/sdk.go
index b1c8aeb..afc6aa4 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -93,6 +93,10 @@
 	//   dropped. Adding a rule to members that have //visibility:private will
 	//   cause the //visibility:private to be discarded.
 	Prebuilt_visibility []string
+
+	// Specifying whether the generated prebuilt SDK build rule should have the
+	// prefer flag set or not.
+	Prebuilts_prefer *bool // default: false
 }
 
 // Contains information about the sdk properties that list sdk members, e.g.
@@ -292,6 +296,10 @@
 	return s.properties.Snapshot
 }
 
+func (s *sdk) PreferPrebuilts() bool {
+	return proptools.BoolDefault(s.properties.Prebuilts_prefer, false)
+}
+
 func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if s.snapshot() {
 		// We don't need to create a snapshot out of sdk_snapshot.
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index a13b0d7..0933db2 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -662,3 +662,68 @@
 		)
 	})
 }
+
+// Ensure that sdk prebuilt_prefer works correctly.
+func TestSnapshot_PrebuiltPreferTrue(t *testing.T) {
+	bp := `
+		sdk {
+			name: "mysdk",
+			java_header_libs: ["myjavalib"],
+			prebuilts_prefer: true,
+		}
+
+		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("prefer=true", func(t *testing.T) {
+		result := android.GroupFixturePreparers(
+			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: true,
+    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"],
+}
+			`),
+		)
+	})
+}
diff --git a/sdk/update.go b/sdk/update.go
index b146b62..2ab45d7 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -32,8 +32,9 @@
 // ========================================================
 //
 // SOONG_SDK_SNAPSHOT_PREFER
-//     By default every unversioned module in the generated snapshot has prefer: false. Building it
-//     with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
+//     By default every unversioned module in the generated snapshot has prefer set by the
+//     sdk.prebuilts_prefer property. Building it with SOONG_SDK_SNAPSHOT_PREFER=true will force
+//     them to use prefer: true.
 //
 // SOONG_SDK_SNAPSHOT_VERSION
 //     This provides control over the version of the generated snapshot.
@@ -1623,11 +1624,11 @@
 
 	// Do not add the prefer property if the member snapshot module is a source module type.
 	if !memberType.UsesSourceModuleTypeInSnapshot() {
-		// Set the prefer based on the environment variable. This is a temporary work around to allow a
-		// snapshot to be created that sets prefer: true.
+		// Set the prefer based on the environment variable if present, else the sdk.prefer_prebuilts
+		// value.
 		// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
 		//  dynamically at build time not at snapshot generation time.
-		prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
+		prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER") || s.PreferPrebuilts()
 
 		// Set prefer. Setting this to false is not strictly required as that is the default but it does
 		// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to