diff options
Diffstat (limited to 'android')
-rw-r--r-- | android/allowlists/allowlists.go | 1 | ||||
-rw-r--r-- | android/androidmk.go | 2 | ||||
-rw-r--r-- | android/api_levels.go | 2 | ||||
-rw-r--r-- | android/bazel.go | 22 | ||||
-rw-r--r-- | android/bazel_handler.go | 8 | ||||
-rw-r--r-- | android/bazel_test.go | 147 | ||||
-rw-r--r-- | android/buildinfo_prop.go | 2 | ||||
-rw-r--r-- | android/config.go | 42 | ||||
-rw-r--r-- | android/gen_notice.go | 2 | ||||
-rw-r--r-- | android/metrics.go | 2 | ||||
-rw-r--r-- | android/module.go | 23 | ||||
-rw-r--r-- | android/mutator.go | 20 | ||||
-rw-r--r-- | android/register.go | 52 | ||||
-rw-r--r-- | android/test_suites.go | 2 | ||||
-rw-r--r-- | android/testing.go | 12 |
15 files changed, 309 insertions, 30 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index e22eec564..751a4cb83 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -223,6 +223,7 @@ var ( "frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively, "frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue, "frameworks/libs/modules-utils/build": Bp2BuildDefaultTrueRecursively, + "frameworks/libs/net/common/native": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/gui": Bp2BuildDefaultTrue, diff --git a/android/androidmk.go b/android/androidmk.go index aa411d116..62f82f247 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -42,7 +42,7 @@ func init() { } func RegisterAndroidMkBuildComponents(ctx RegistrationContext) { - ctx.RegisterSingletonType("androidmk", AndroidMkSingleton) + ctx.RegisterParallelSingletonType("androidmk", AndroidMkSingleton) } // Enable androidmk support. diff --git a/android/api_levels.go b/android/api_levels.go index fa919fda7..2391e6cc2 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -22,7 +22,7 @@ import ( ) func init() { - RegisterSingletonType("api_levels", ApiLevelsSingleton) + RegisterParallelSingletonType("api_levels", ApiLevelsSingleton) } const previewAPILevelBase = 9000 diff --git a/android/bazel.go b/android/bazel.go index 114b1f5c2..d32663483 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -46,6 +46,10 @@ const ( // that is not a platform incompatibility. Example: the module-type is not // enabled, or is not bp2build-converted. ModuleIncompatibility + + // Missing dependencies. We can't query Bazel for modules if it has missing dependencies, there + // will be failures. + ModuleMissingDeps ) // FileGroupAsLibrary describes a filegroup module that is converted to some library @@ -367,16 +371,26 @@ func GetBp2BuildAllowList() Bp2BuildConversionAllowlist { // As a side effect, calling this method will also log whether this module is // mixed build enabled for metrics reporting. func MixedBuildsEnabled(ctx BaseModuleContext) MixedBuildEnabledStatus { - module := ctx.Module() - apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo) - withinApex := !apexInfo.IsForPlatform() - platformIncompatible := isPlatformIncompatible(ctx.Os(), ctx.Arch().ArchType) if platformIncompatible { ctx.Config().LogMixedBuild(ctx, false) return TechnicalIncompatibility } + if ctx.Config().AllowMissingDependencies() { + missingDeps := ctx.getMissingDependencies() + // If there are missing dependencies, querying Bazel will fail. Soong instead fails at execution + // time, not loading/analysis. disable mixed builds and fall back to Soong to maintain that + // behavior. + if len(missingDeps) > 0 { + ctx.Config().LogMixedBuild(ctx, false) + return ModuleMissingDeps + } + } + + module := ctx.Module() + apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo) + withinApex := !apexInfo.IsForPlatform() mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() && module.Enabled() && convertedToBazel(ctx, module) && diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 10cf60a0a..35f880cf4 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -74,14 +74,12 @@ var ( } ) -func init() { - RegisterMixedBuildsMutator(InitRegistrationContext) +func registerMixedBuildsMutator(ctx RegisterMutatorsContext) { + ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel() } func RegisterMixedBuildsMutator(ctx RegistrationContext) { - ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { - ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel() - }) + ctx.FinalDepsMutators(registerMixedBuildsMutator) } func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) { diff --git a/android/bazel_test.go b/android/bazel_test.go index 77e251575..13fd40849 100644 --- a/android/bazel_test.go +++ b/android/bazel_test.go @@ -436,3 +436,150 @@ func TestShouldKeepExistingBuildFileForDir(t *testing.T) { } } } + +type mixedBuildModule struct { + ModuleBase + BazelModuleBase + props struct { + Deps []string + Mixed_build_incompatible *bool + QueuedBazelCall bool `blueprint:"mutated"` + } +} + +type mixedBuildModuleInfo struct { + QueuedBazelCall bool +} + +var mixedBuildModuleProvider = blueprint.NewProvider(mixedBuildModuleInfo{}) + +func mixedBuildModuleFactory() Module { + m := &mixedBuildModule{} + m.AddProperties(&m.props) + InitAndroidArchModule(m, HostAndDeviceDefault, MultilibBoth) + InitBazelModule(m) + + return m +} + +func (m *mixedBuildModule) ConvertWithBp2build(ctx TopDownMutatorContext) { +} + +func (m *mixedBuildModule) DepsMutator(ctx BottomUpMutatorContext) { + ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...) +} + +func (m *mixedBuildModule) GenerateAndroidBuildActions(ctx ModuleContext) { +} + +func (m *mixedBuildModule) IsMixedBuildSupported(ctx BaseModuleContext) bool { + return !proptools.Bool(m.props.Mixed_build_incompatible) +} + +func (m *mixedBuildModule) QueueBazelCall(ctx BaseModuleContext) { + m.props.QueuedBazelCall = true +} + +func (m *mixedBuildModule) ProcessBazelQueryResponse(ctx ModuleContext) { + ctx.SetProvider(mixedBuildModuleProvider, mixedBuildModuleInfo{ + QueuedBazelCall: m.props.QueuedBazelCall, + }) +} + +var prepareForMixedBuildTests = FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("deps", mixedBuildModuleFactory) + RegisterMixedBuildsMutator(ctx) +}) + +func TestMixedBuildsEnabledForType(t *testing.T) { + baseBp := ` + deps { + name: "foo", + deps: ["bar"], + target: { windows: { enabled: true } }, + %s + } +` + depBp := ` + deps { + name: "bar", + target: { + windows: { + enabled: true, + }, + }, + } +` + testCases := []struct { + desc string + variant *string + missingDeps bool + extraBpInfo string + mixedBuildsEnabled bool + }{ + { + desc: "mixed builds works", + mixedBuildsEnabled: true, + extraBpInfo: `bazel_module: { bp2build_available: true },`, + }, + { + desc: "missing deps", + missingDeps: true, + mixedBuildsEnabled: false, + extraBpInfo: `bazel_module: { bp2build_available: true },`, + }, + { + desc: "windows no mixed builds", + mixedBuildsEnabled: false, + variant: proptools.StringPtr("windows_x86"), + extraBpInfo: `bazel_module: { bp2build_available: true },`, + }, + { + desc: "mixed builds disabled by type", + mixedBuildsEnabled: false, + extraBpInfo: `mixed_build_incompatible: true, + bazel_module: { bp2build_available: true },`, + }, + { + desc: "mixed builds not bp2build available", + mixedBuildsEnabled: false, + extraBpInfo: `bazel_module: { bp2build_available: false },`, + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + handlers := GroupFixturePreparers( + prepareForMixedBuildTests, + PrepareForTestWithArchMutator, + FixtureModifyConfig(func(config Config) { + config.BazelContext = MockBazelContext{ + OutputBaseDir: "base", + } + config.Targets[Windows] = []Target{ + {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true}, + {Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true}, + } + }), + ) + bp := fmt.Sprintf(baseBp, tc.extraBpInfo) + if tc.missingDeps { + handlers = GroupFixturePreparers( + handlers, + PrepareForTestWithAllowMissingDependencies, + ) + } else { + bp += depBp + } + result := handlers.RunTestWithBp(t, bp) + + variant := proptools.StringDefault(tc.variant, "android_arm64_armv8-a") + + m := result.ModuleForTests("foo", variant) + mixedBuildModuleInfo := result.TestContext.ModuleProvider(m.Module(), mixedBuildModuleProvider).(mixedBuildModuleInfo) + if w, g := tc.mixedBuildsEnabled, mixedBuildModuleInfo.QueuedBazelCall; w != g { + t.Errorf("Expected mixed builds enabled %t, got mixed builds enabled %t", w, g) + } + }) + } +} diff --git a/android/buildinfo_prop.go b/android/buildinfo_prop.go index 46f648802..8e19ad5f4 100644 --- a/android/buildinfo_prop.go +++ b/android/buildinfo_prop.go @@ -23,7 +23,7 @@ import ( func init() { ctx := InitRegistrationContext - ctx.RegisterSingletonModuleType("buildinfo_prop", buildinfoPropFactory) + ctx.RegisterParallelSingletonModuleType("buildinfo_prop", buildinfoPropFactory) } type buildinfoPropProperties struct { diff --git a/android/config.go b/android/config.go index 01b8cfaa3..d0f2ea44c 100644 --- a/android/config.go +++ b/android/config.go @@ -302,6 +302,9 @@ type config struct { // modules that aren't mixed-built for at least one variant will cause a build // failure ensureAllowlistIntegrity bool + + // List of Api libraries that contribute to Api surfaces. + apiLibraries map[string]struct{} } type deviceConfig struct { @@ -622,6 +625,33 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) config.BazelContext, err = NewBazelContext(config) config.Bp2buildPackageConfig = GetBp2BuildAllowList() + // TODO(b/276958307): Replace the hardcoded list to a sdk_library local prop. + config.apiLibraries = map[string]struct{}{ + "android.net.ipsec.ike": {}, + "art.module.public.api": {}, + "conscrypt.module.public.api": {}, + "framework-adservices": {}, + "framework-appsearch": {}, + "framework-bluetooth": {}, + "framework-connectivity": {}, + "framework-connectivity-t": {}, + "framework-graphics": {}, + "framework-media": {}, + "framework-mediaprovider": {}, + "framework-ondevicepersonalization": {}, + "framework-permission": {}, + "framework-permission-s": {}, + "framework-scheduling": {}, + "framework-sdkextensions": {}, + "framework-statsd": {}, + "framework-sdksandbox": {}, + "framework-tethering": {}, + "framework-uwb": {}, + "framework-virtualization": {}, + "framework-wifi": {}, + "i18n.module.public.api": {}, + } + return Config{config}, err } @@ -1983,8 +2013,20 @@ func (c *config) BuildFromTextStub() bool { func (c *config) SetBuildFromTextStub(b bool) { c.buildFromTextStub = b } + func (c *config) AddForceEnabledModules(forceEnabled []string) { for _, forceEnabledModule := range forceEnabled { c.bazelForceEnabledModules[forceEnabledModule] = struct{}{} } } + +func (c *config) SetApiLibraries(libs []string) { + c.apiLibraries = make(map[string]struct{}) + for _, lib := range libs { + c.apiLibraries[lib] = struct{}{} + } +} + +func (c *config) GetApiLibraries() map[string]struct{} { + return c.apiLibraries +} diff --git a/android/gen_notice.go b/android/gen_notice.go index 091345b9f..1acc638e8 100644 --- a/android/gen_notice.go +++ b/android/gen_notice.go @@ -28,7 +28,7 @@ func init() { // Register the gen_notice module type. func RegisterGenNoticeBuildComponents(ctx RegistrationContext) { - ctx.RegisterSingletonType("gen_notice_build_rules", GenNoticeBuildRulesFactory) + ctx.RegisterParallelSingletonType("gen_notice_build_rules", GenNoticeBuildRulesFactory) ctx.RegisterModuleType("gen_notice", GenNoticeFactory) } diff --git a/android/metrics.go b/android/metrics.go index 3d41a1d6c..63c72cd97 100644 --- a/android/metrics.go +++ b/android/metrics.go @@ -42,7 +42,7 @@ func readSoongMetrics(config Config) (SoongMetrics, bool) { } func init() { - RegisterSingletonType("soong_metrics", soongMetricsSingletonFactory) + RegisterParallelSingletonType("soong_metrics", soongMetricsSingletonFactory) } func soongMetricsSingletonFactory() Singleton { return soongMetricsSingleton{} } diff --git a/android/module.go b/android/module.go index db602a0aa..604ba2401 100644 --- a/android/module.go +++ b/android/module.go @@ -354,6 +354,10 @@ type BaseModuleContext interface { AddMissingDependencies(missingDeps []string) + // getMissingDependencies returns the list of missing dependencies. + // Calling this function prevents adding new dependencies. + getMissingDependencies() []string + // AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build AddUnconvertedBp2buildDep(dep string) @@ -939,7 +943,8 @@ type commonProperties struct { NamespaceExportedToMake bool `blueprint:"mutated"` - MissingDeps []string `blueprint:"mutated"` + MissingDeps []string `blueprint:"mutated"` + CheckedMissingDeps bool `blueprint:"mutated"` // Name and variant strings stored by mutators to enable Module.String() DebugName string `blueprint:"mutated"` @@ -2862,6 +2867,20 @@ func (b *baseModuleContext) AddMissingDependencies(deps []string) { } } +func (b *baseModuleContext) checkedMissingDeps() bool { + return b.Module().base().commonProperties.CheckedMissingDeps +} + +func (b *baseModuleContext) getMissingDependencies() []string { + checked := &b.Module().base().commonProperties.CheckedMissingDeps + *checked = true + var missingDeps []string + missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...) + missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...) + missingDeps = FirstUniqueStrings(missingDeps) + return missingDeps +} + type AllowDisabledModuleDependency interface { blueprint.DependencyTag AllowDisabledModuleDependency(target Module) bool @@ -3724,7 +3743,7 @@ func (m *moduleContext) TargetRequiredModuleNames() []string { } func init() { - RegisterSingletonType("buildtarget", BuildTargetSingleton) + RegisterParallelSingletonType("buildtarget", BuildTargetSingleton) } func BuildTargetSingleton() Singleton { diff --git a/android/mutator.go b/android/mutator.go index 0a091eb6f..41853154f 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -67,6 +67,8 @@ func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []Registe // collateGloballyRegisteredMutators constructs the list of mutators that have been registered // with the InitRegistrationContext and will be used at runtime. func collateGloballyRegisteredMutators() sortableComponents { + // ensure mixed builds mutator is the last mutator + finalDeps = append(finalDeps, registerMixedBuildsMutator) return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps) } @@ -885,10 +887,16 @@ func (b *bottomUpMutatorContext) Rename(name string) { } func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } return b.bp.AddDependency(module, tag, name...) } func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } b.bp.AddReverseDependency(module, tag, name) } @@ -938,11 +946,17 @@ func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } return b.bp.AddVariationDependencies(variations, tag, names...) } func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } return b.bp.AddFarVariationDependencies(variations, tag, names...) } @@ -952,10 +966,16 @@ func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.Depende } func (b *bottomUpMutatorContext) ReplaceDependencies(name string) { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } b.bp.ReplaceDependencies(name) } func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) { + if b.baseModuleContext.checkedMissingDeps() { + panic("Adding deps not allowed after checking for missing deps") + } b.bp.ReplaceDependenciesIf(name, predicate) } diff --git a/android/register.go b/android/register.go index 1a3db9d90..64b0207e7 100644 --- a/android/register.go +++ b/android/register.go @@ -65,16 +65,19 @@ type singleton struct { // True if this should be registered as a pre-singleton, false otherwise. pre bool + // True if this should be registered as a parallel singleton. + parallel bool + name string factory SingletonFactory } -func newSingleton(name string, factory SingletonFactory) singleton { - return singleton{false, name, factory} +func newSingleton(name string, factory SingletonFactory, parallel bool) singleton { + return singleton{pre: false, parallel: parallel, name: name, factory: factory} } func newPreSingleton(name string, factory SingletonFactory) singleton { - return singleton{true, name, factory} + return singleton{pre: true, parallel: false, name: name, factory: factory} } func (s singleton) componentName() string { @@ -86,7 +89,7 @@ func (s singleton) register(ctx *Context) { if s.pre { ctx.RegisterPreSingletonType(s.name, adaptor) } else { - ctx.RegisterSingletonType(s.name, adaptor) + ctx.RegisterSingletonType(s.name, adaptor, s.parallel) } } @@ -145,8 +148,16 @@ func RegisterModuleTypeForDocs(name string, factory reflect.Value) { moduleTypeByFactory[factory] = name } +func registerSingletonType(name string, factory SingletonFactory, parallel bool) { + singletons = append(singletons, newSingleton(name, factory, parallel)) +} + func RegisterSingletonType(name string, factory SingletonFactory) { - singletons = append(singletons, newSingleton(name, factory)) + registerSingletonType(name, factory, false) +} + +func RegisterParallelSingletonType(name string, factory SingletonFactory) { + registerSingletonType(name, factory, true) } func RegisterPreSingletonType(name string, factory SingletonFactory) { @@ -220,17 +231,17 @@ func (ctx *Context) registerSingletonMakeVarsProvider(makevars SingletonMakeVars func collateGloballyRegisteredSingletons() sortableComponents { allSingletons := append(sortableComponents(nil), singletons...) allSingletons = append(allSingletons, - singleton{false, "bazeldeps", BazelSingleton}, + singleton{pre: false, parallel: true, name: "bazeldeps", factory: BazelSingleton}, // Register phony just before makevars so it can write out its phony rules as Make rules - singleton{false, "phony", phonySingletonFactory}, + singleton{pre: false, parallel: false, name: "phony", factory: phonySingletonFactory}, // Register makevars after other singletons so they can export values through makevars - singleton{false, "makevars", makeVarsSingletonFunc}, + singleton{pre: false, parallel: false, name: "makevars", factory: makeVarsSingletonFunc}, // Register env and ninjadeps last so that they can track all used environment variables and // Ninja file dependencies stored in the config. - singleton{false, "ninjadeps", ninjaDepsSingletonFactory}, + singleton{pre: false, parallel: false, name: "ninjadeps", factory: ninjaDepsSingletonFactory}, ) return allSingletons @@ -259,7 +270,9 @@ func ModuleTypeByFactory() map[reflect.Value]string { type RegistrationContext interface { RegisterModuleType(name string, factory ModuleFactory) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) + RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) RegisterPreSingletonType(name string, factory SingletonFactory) + RegisterParallelSingletonType(name string, factory SingletonFactory) RegisterSingletonType(name string, factory SingletonFactory) PreArchMutators(f RegisterMutatorFunc) @@ -315,8 +328,15 @@ func (ctx *initRegistrationContext) RegisterModuleType(name string, factory Modu } func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) { + ctx.registerSingletonModuleType(name, factory, false) +} +func (ctx *initRegistrationContext) RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) { + ctx.registerSingletonModuleType(name, factory, true) +} + +func (ctx *initRegistrationContext) registerSingletonModuleType(name string, factory SingletonModuleFactory, parallel bool) { s, m := SingletonModuleFactoryAdaptor(name, factory) - ctx.RegisterSingletonType(name, s) + ctx.registerSingletonType(name, s, parallel) ctx.RegisterModuleType(name, m) // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the @@ -324,12 +344,20 @@ func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, fac RegisterModuleTypeForDocs(name, reflect.ValueOf(factory)) } -func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) { +func (ctx *initRegistrationContext) registerSingletonType(name string, factory SingletonFactory, parallel bool) { if _, present := ctx.singletonTypes[name]; present { panic(fmt.Sprintf("singleton type %q is already registered", name)) } ctx.singletonTypes[name] = factory - RegisterSingletonType(name, factory) + registerSingletonType(name, factory, parallel) +} + +func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) { + ctx.registerSingletonType(name, factory, false) +} + +func (ctx *initRegistrationContext) RegisterParallelSingletonType(name string, factory SingletonFactory) { + ctx.registerSingletonType(name, factory, true) } func (ctx *initRegistrationContext) RegisterPreSingletonType(name string, factory SingletonFactory) { diff --git a/android/test_suites.go b/android/test_suites.go index b570b2383..b48d71af6 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -15,7 +15,7 @@ package android func init() { - RegisterSingletonType("testsuites", testSuiteFilesFactory) + RegisterParallelSingletonType("testsuites", testSuiteFilesFactory) } func testSuiteFilesFactory() Singleton { diff --git a/android/testing.go b/android/testing.go index 2a9c6584e..5ad7ad07f 100644 --- a/android/testing.go +++ b/android/testing.go @@ -495,8 +495,18 @@ func (ctx *TestContext) RegisterSingletonModuleType(name string, factory Singlet ctx.RegisterModuleType(name, m) } +func (ctx *TestContext) RegisterParallelSingletonModuleType(name string, factory SingletonModuleFactory) { + s, m := SingletonModuleFactoryAdaptor(name, factory) + ctx.RegisterParallelSingletonType(name, s) + ctx.RegisterModuleType(name, m) +} + func (ctx *TestContext) RegisterSingletonType(name string, factory SingletonFactory) { - ctx.singletons = append(ctx.singletons, newSingleton(name, factory)) + ctx.singletons = append(ctx.singletons, newSingleton(name, factory, false)) +} + +func (ctx *TestContext) RegisterParallelSingletonType(name string, factory SingletonFactory) { + ctx.singletons = append(ctx.singletons, newSingleton(name, factory, true)) } func (ctx *TestContext) RegisterPreSingletonType(name string, factory SingletonFactory) { |