Use LoadHook to create modules in java_sdk_library

Creating new modules in a mutator is dangerous, as other mutators
that need to see the new modules may already have run, in this case
the prebuilts mutator.  Move SdkLibraryMutator to a LoadHook instead.
Also moves registering the LoadHook mutator to testing.go so it is
registered for all tests.

Test: m checkbuild
Change-Id: I08bd76a0e6205d2ca27861058067a1562c339eed
diff --git a/android/hooks.go b/android/hooks.go
index 6b2468d..d55678e 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -123,6 +123,10 @@
 	install []func(InstallHookContext)
 }
 
+func registerLoadHookMutator(ctx RegisterMutatorsContext) {
+	ctx.TopDown("load_hooks", LoadHookMutator).Parallel()
+}
+
 func LoadHookMutator(ctx TopDownMutatorContext) {
 	if m, ok := ctx.Module().(Module); ok {
 		// Cast through *androidTopDownMutatorContext because AppendProperties is implemented
diff --git a/android/mutator.go b/android/mutator.go
index 71237a1..5ce743a 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -73,9 +73,7 @@
 type RegisterMutatorFunc func(RegisterMutatorsContext)
 
 var preArch = []RegisterMutatorFunc{
-	func(ctx RegisterMutatorsContext) {
-		ctx.TopDown("load_hooks", LoadHookMutator).Parallel()
-	},
+	registerLoadHookMutator,
 	RegisterNamespaceMutator,
 	RegisterPrebuiltsPreArchMutators,
 	RegisterDefaultsPreArchMutators,
diff --git a/android/testing.go b/android/testing.go
index 0ec5af5..aee6855 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -37,6 +37,8 @@
 
 	ctx.SetNameInterface(nameResolver)
 
+	ctx.preArch = append(ctx.preArch, registerLoadHookMutator)
+
 	ctx.postDeps = append(ctx.postDeps, registerPathDepsMutator)
 
 	return ctx
diff --git a/java/java_test.go b/java/java_test.go
index 3ae993d..89f871c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -94,7 +94,6 @@
 	ctx.PreArchMutators(android.RegisterOverridePreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
-		ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
 	})
 	ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
 	ctx.RegisterPreSingletonType("sdk", android.SingletonFactoryAdaptor(sdkSingletonFactory))
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 72cce57..3bda9c7 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -42,10 +42,6 @@
 	name string
 }
 
-type syspropLibraryInterface interface {
-	SyspropJavaModule() *SdkLibrary
-}
-
 var (
 	publicApiStubsTag = dependencyTag{name: "public"}
 	systemApiStubsTag = dependencyTag{name: "system"}
@@ -80,10 +76,6 @@
 func init() {
 	android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
 
-	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
-	})
-
 	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
 		javaSdkLibraries := javaSdkLibraries(ctx.Config())
 		sort.Strings(*javaSdkLibraries)
@@ -376,7 +368,7 @@
 }
 
 // Creates a static java library that has API stubs
-func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
+func (module *SdkLibrary) createStubsLibrary(mctx android.LoadHookContext, apiScope apiScope) {
 	props := struct {
 		Name              *string
 		Srcs              []string
@@ -435,7 +427,7 @@
 
 // Creates a droiddoc module that creates stubs source files from the given full source
 // files
-func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
+func (module *SdkLibrary) createDocs(mctx android.LoadHookContext, apiScope apiScope) {
 	props := struct {
 		Name                             *string
 		Srcs                             []string
@@ -534,7 +526,7 @@
 }
 
 // Creates the xml file that publicizes the runtime library
-func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
+func (module *SdkLibrary) createXmlFile(mctx android.LoadHookContext) {
 	template := `
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2018 The Android Open Source Project
@@ -659,15 +651,7 @@
 // For a java_sdk_library module, create internal modules for stubs, docs,
 // runtime libs and xml file. If requested, the stubs and docs are created twice
 // once for public API level and once for system API level
-func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
-	if module, ok := mctx.Module().(*SdkLibrary); ok {
-		module.createInternalModules(mctx)
-	} else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
-		module.SyspropJavaModule().createInternalModules(mctx)
-	}
-}
-
-func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
+func (module *SdkLibrary) CreateInternalModules(mctx android.LoadHookContext) {
 	if len(module.Library.Module.properties.Srcs) == 0 {
 		mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
 	}
@@ -744,5 +728,6 @@
 	module := &SdkLibrary{}
 	module.InitSdkLibraryProperties()
 	InitJavaModule(module, android.HostAndDeviceSupported)
+	android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.CreateInternalModules(ctx) })
 	return module
 }
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 48078d8..0313ecd 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -18,6 +18,7 @@
 	"android/soong/android"
 	"android/soong/cc"
 	"android/soong/java"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
@@ -63,10 +64,6 @@
 	return "lib" + m.Name()
 }
 
-func (m *syspropLibrary) SyspropJavaModule() *java.SdkLibrary {
-	return &m.SdkLibrary
-}
-
 func syspropLibraryFactory() android.Module {
 	m := &syspropLibrary{}
 
@@ -77,7 +74,7 @@
 	m.InitSdkLibraryProperties()
 	android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common")
 	android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
-
+	android.AddLoadHook(m, func(ctx android.LoadHookContext) { m.SdkLibrary.CreateInternalModules(ctx) })
 	return m
 }
 
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index af89c24..e90519e 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -61,15 +61,11 @@
 	ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
 	ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(java.SystemModulesFactory))
 	ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(java.PrebuiltApisFactory))
-	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("load_hooks", android.LoadHookMutator).Parallel()
-	})
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("prebuilt_apis", java.PrebuiltApisMutator).Parallel()
-		ctx.TopDown("java_sdk_library", java.SdkLibraryMutator).Parallel()
 	})
 
 	ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))