Add java_* 'services:' field

Some libraries rely on the java.util.ServiceLoader system to access
classes. Allow java_* targets to specify the services that should be
exposed there.

Test: m jdi-support
Bug: 124507633

Change-Id: I253a87033563e3aebc50250fe2252d80d2883815
diff --git a/java/java.go b/java/java.go
index 3501174..ecc3608 100644
--- a/java/java.go
+++ b/java/java.go
@@ -168,6 +168,9 @@
 	}
 
 	Instrument bool `blueprint:"mutated"`
+
+	// List of files to include in the META-INF/services folder of the resulting jar.
+	Services []string `android:"arch_variant"`
 }
 
 type CompilerDeviceProperties struct {
@@ -478,6 +481,7 @@
 	android.ExtractSourcesDeps(ctx, j.properties.Java_resources)
 	android.ExtractSourceDeps(ctx, j.properties.Manifest)
 	android.ExtractSourceDeps(ctx, j.properties.Jarjar_rules)
+	android.ExtractSourcesDeps(ctx, j.properties.Services)
 
 	if j.hasSrcExt(".proto") {
 		protoDeps(ctx, &j.protoProperties)
@@ -1136,6 +1140,25 @@
 		manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
 	}
 
+	services := ctx.ExpandSources(j.properties.Services, nil)
+	if len(services) > 0 {
+		servicesJar := android.PathForModuleOut(ctx, "services", jarName)
+		var zipargs []string
+		for _, file := range services {
+			serviceFile := file.String()
+			zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
+		}
+		ctx.Build(pctx, android.BuildParams{
+			Rule:      zip,
+			Output:    servicesJar,
+			Implicits: services,
+			Args: map[string]string{
+				"jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscape(zipargs), " "),
+			},
+		})
+		jars = append(jars, servicesJar)
+	}
+
 	// Combine the classes built from sources, any manifests, and any static libraries into
 	// classes.jar. If there is only one input jar this step will be skipped.
 	var outputFile android.ModuleOutPath