Add support for R8 partial compilation in soong

This adds a new property Optimize.Exclude, which takes a path to a file containing a list of class names that should not be compiled using R8.

Example:

$ cat r8.exclude:
com.example.Foo
com.example.Bar
com.example.Bar

By default all classes are compiled using R8 when Optimize.Enabled is set.

Bug: 376196706
Test: existing
Change-Id: Ibc62f137e9c9251618d4ffbb655bc41b8b5b95e9
diff --git a/java/dex.go b/java/dex.go
index ed2df21..b32d5ae 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -103,6 +103,19 @@
 		// If true, transitive reverse dependencies of this module will have this
 		// module's proguard spec appended to their optimization action
 		Export_proguard_flags_files *bool
+
+		// Path to a file containing a list of class names that should not be compiled using R8.
+		// These classes will be compiled by D8 similar to when Optimize.Enabled is false.
+		//
+		// Example:
+		//
+		//   r8.exclude:
+		//   com.example.Foo
+		//   com.example.Bar
+		//   com.example.Bar$Baz
+		//
+		// By default all classes are compiled using R8 when Optimize.Enabled is set.
+		Exclude *string `android:"path"`
 	}
 
 	// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -528,6 +541,11 @@
 		r8Flags = append(r8Flags, "--store-store-fence-constructor-inlining")
 	}
 
+	if opt.Exclude != nil {
+		r8Flags = append(r8Flags, "--exclude", *opt.Exclude)
+		r8Deps = append(r8Deps, android.PathForModuleSrc(ctx, *opt.Exclude))
+	}
+
 	return r8Flags, r8Deps, artProfileOutput
 }