Add support for java_defaults modules

Test: java_test.go
Change-Id: I6dba1671c7eb019183af94bb7b10810296740101
diff --git a/android/defaults.go b/android/defaults.go
index 3ec3ff4..4bf872e 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -117,7 +117,7 @@
 	}
 }
 
-func registerDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
+func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
 	ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
 	ctx.TopDown("defaults", defaultsMutator).Parallel()
 }
diff --git a/android/mutator.go b/android/mutator.go
index 86a5b85..c8f3e8f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -75,7 +75,7 @@
 		ctx.TopDown("load_hooks", loadHookMutator).Parallel()
 	},
 	registerPrebuiltsPreArchMutators,
-	registerDefaultsPreArchMutators,
+	RegisterDefaultsPreArchMutators,
 }
 
 var preDeps = []RegisterMutatorFunc{
diff --git a/java/java.go b/java/java.go
index 3d2e960..dfdf641 100644
--- a/java/java.go
+++ b/java/java.go
@@ -30,6 +30,8 @@
 )
 
 func init() {
+	android.RegisterModuleType("java_defaults", defaultsFactory)
+
 	android.RegisterModuleType("java_library", JavaLibraryFactory)
 	android.RegisterModuleType("java_library_static", JavaLibraryFactory)
 	android.RegisterModuleType("java_library_host", JavaLibraryHostFactory)
@@ -55,7 +57,7 @@
 // DroidDoc
 // Findbugs
 
-type compilerProperties struct {
+type CompilerProperties struct {
 	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
 	// or .aidl files.
 	Srcs []string `android:"arch_variant"`
@@ -90,7 +92,7 @@
 	Jarjar_rules *string
 }
 
-type compilerDeviceProperties struct {
+type CompilerDeviceProperties struct {
 	// list of module-specific flags that will be used for dex compiles
 	Dxflags []string `android:"arch_variant"`
 
@@ -112,9 +114,10 @@
 // Module contains the properties and members used by all java module types
 type Module struct {
 	android.ModuleBase
+	android.DefaultableModuleBase
 
-	properties       compilerProperties
-	deviceProperties compilerDeviceProperties
+	properties       CompilerProperties
+	deviceProperties CompilerDeviceProperties
 
 	// output file suitable for inserting into the classpath of another compile
 	classpathFile android.Path
@@ -147,6 +150,11 @@
 	AidlIncludeDirs() android.Paths
 }
 
+func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
+	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+}
+
 type dependencyTag struct {
 	blueprint.BaseDependencyTag
 	name string
@@ -440,7 +448,7 @@
 		&module.Module.properties,
 		&module.Module.deviceProperties)
 
-	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+	InitJavaModule(module, android.HostAndDeviceSupported)
 	return module
 }
 
@@ -449,7 +457,7 @@
 
 	module.AddProperties(&module.Module.properties)
 
-	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+	InitJavaModule(module, android.HostSupported)
 	return module
 }
 
@@ -491,7 +499,7 @@
 		&module.Module.deviceProperties,
 		&module.binaryProperties)
 
-	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+	InitJavaModule(module, android.HostAndDeviceSupported)
 	return module
 }
 
@@ -503,7 +511,7 @@
 		&module.Module.deviceProperties,
 		&module.binaryProperties)
 
-	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+	InitJavaModule(module, android.HostSupported)
 	return module
 }
 
@@ -616,3 +624,35 @@
 	}
 	return false
 }
+
+//
+// Defaults
+//
+type Defaults struct {
+	android.ModuleBase
+	android.DefaultsModuleBase
+}
+
+func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+}
+
+func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
+}
+
+func defaultsFactory() android.Module {
+	return DefaultsFactory()
+}
+
+func DefaultsFactory(props ...interface{}) android.Module {
+	module := &Defaults{}
+
+	module.AddProperties(props...)
+	module.AddProperties(
+		&CompilerProperties{},
+		&CompilerDeviceProperties{},
+	)
+
+	android.InitDefaultsModule(module)
+
+	return module
+}
diff --git a/java/java_test.go b/java/java_test.go
index bd6451c..6ebaa34 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -56,6 +56,8 @@
 	ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
 	ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(JavaLibraryFactory))
 	ctx.RegisterModuleType("java_prebuilt_library", android.ModuleFactoryAdaptor(JavaPrebuiltFactory))
+	ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.Register()
 
 	extraModules := []string{"core-libart", "frameworks", "sdk_v14"}
@@ -230,6 +232,49 @@
 	}
 }
 
+func TestDefaults(t *testing.T) {
+	ctx := testJava(t, `
+		java_defaults {
+			name: "defaults",
+			srcs: ["a.java"],
+			libs: ["bar"],
+			static_libs: ["baz"],
+		}
+
+		java_library {
+			name: "foo",
+			defaults: ["defaults"],
+		}
+
+		java_library {
+			name: "bar",
+			srcs: ["b.java"],
+		}
+
+		java_library {
+			name: "baz",
+			srcs: ["c.java"],
+		}
+		`)
+
+	javac := ctx.ModuleForTests("foo", "").Rule("javac")
+	jar := ctx.ModuleForTests("foo", "").Rule("jar")
+
+	if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
+		t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
+	}
+
+	bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar")
+	if !strings.Contains(javac.Args["classpath"], bar) {
+		t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
+	}
+
+	baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list")
+	if !strings.Contains(jar.Args["jarArgs"], baz) {
+		t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz)
+	}
+}
+
 func fail(t *testing.T, errs []error) {
 	if len(errs) > 0 {
 		for _, err := range errs {