Merge changes from topic "apex_contributions_build_flags" into main
* changes:
Special-case java_sdk_library in source vs prebuilt selection
Use `all_apex_contributions` for source/prebuilts selection
Create a singleton all_apex_contributions module type
diff --git a/Android.bp b/Android.bp
index 63de015..b1db8e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -130,3 +130,8 @@
// Currently, only microdroid can refer to buildinfo.prop
visibility: ["//packages/modules/Virtualization/microdroid"],
}
+
+// container for apex_contributions selected using build flags
+all_apex_contributions {
+ name: "all_apex_contributions",
+}
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index a28ac31..6eaca8b 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -15,6 +15,7 @@
package android
import (
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -24,6 +25,7 @@
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
+ ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
}
type apexContributions struct {
@@ -65,3 +67,109 @@
// prebuilts selection.
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}
+
+// A container for apex_contributions.
+// Based on product_config, it will create a dependency on the selected
+// apex_contributions per mainline module
+type allApexContributions struct {
+ SingletonModuleBase
+}
+
+func allApexContributionsFactory() SingletonModule {
+ module := &allApexContributions{}
+ InitAndroidModule(module)
+ return module
+}
+
+type apexContributionsDepTag struct {
+ blueprint.BaseDependencyTag
+}
+
+var (
+ acDepTag = apexContributionsDepTag{}
+)
+
+// Creates a dep to each selected apex_contributions
+func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
+ ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
+}
+
+// Set PrebuiltSelectionInfoProvider in post deps phase
+func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
+ addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
+ for _, content := range m.Contents() {
+ if !ctx.OtherModuleExists(content) {
+ ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
+ }
+ pi := &PrebuiltSelectionInfo{
+ baseModuleName: RemoveOptionalPrebuiltPrefix(content),
+ selectedModuleName: content,
+ metadataModuleName: m.Name(),
+ apiDomain: m.ApiDomain(),
+ }
+ p.Add(ctx, pi)
+ }
+ }
+
+ if ctx.Config().Bp2buildMode() { // Skip bp2build
+ return
+ }
+ p := PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
+ if m, ok := child.(*apexContributions); ok {
+ addContentsToProvider(&p, m)
+ } else {
+ ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
+ }
+ })
+ ctx.SetProvider(PrebuiltSelectionInfoProvider, p)
+}
+
+// A provider containing metadata about whether source or prebuilt should be used
+// This provider will be used in prebuilt_select mutator to redirect deps
+var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider(PrebuiltSelectionInfoMap{}, "prebuilt_select")
+
+// Map of baseModuleName to the selected source or prebuilt
+type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
+
+// Add a new entry to the map with some validations
+func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
+ if p == nil {
+ return
+ }
+ // Do not allow dups. If the base module (without the prebuilt_) has been added before, raise an exception.
+ if old, exists := (*pm)[p.baseModuleName]; exists {
+ ctx.ModuleErrorf("Cannot use Soong module: %s from apex_contributions: %s because it has been added previously as: %s from apex_contributions: %s\n",
+ p.selectedModuleName, p.metadataModuleName, old.selectedModuleName, old.metadataModuleName,
+ )
+ }
+ (*pm)[p.baseModuleName] = *p
+}
+
+type PrebuiltSelectionInfo struct {
+ // e.g. libc
+ baseModuleName string
+ // e.g. (libc|prebuilt_libc)
+ selectedModuleName string
+ // Name of the apex_contributions module
+ metadataModuleName string
+ // e.g. com.android.runtime
+ apiDomain string
+}
+
+// Returns true if `name` is explicitly requested using one of the selected
+// apex_contributions metadata modules.
+func (p *PrebuiltSelectionInfoMap) IsSelected(baseModuleName, name string) bool {
+ if i, exists := (*p)[baseModuleName]; exists {
+ return i.selectedModuleName == name
+ } else {
+ return false
+ }
+}
+
+// This module type does not have any build actions.
+func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
+}
+
+func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
+}
diff --git a/android/config.go b/android/config.go
index 4c31bb0..696632a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2129,3 +2129,41 @@
val, ok := c.productVariables.BuildFlags[name]
return val, ok
}
+
+var (
+ mainlineApexContributionBuildFlags = []string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES",
+ "RELEASE_APEX_CONTRIBUTIONS_APPSEARCH",
+ "RELEASE_APEX_CONTRIBUTIONS_ART",
+ "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH",
+ "RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE",
+ "RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY",
+ "RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT",
+ "RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY",
+ "RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK",
+ "RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS",
+ "RELEASE_APEX_CONTRIBUTIONS_IPSEC",
+ "RELEASE_APEX_CONTRIBUTIONS_MEDIA",
+ "RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER",
+ "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION",
+ "RELEASE_APEX_CONTRIBUTIONS_PERMISSION",
+ "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING",
+ "RELEASE_APEX_CONTRIBUTIONS_SCHEDULING",
+ "RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS",
+ "RELEASE_APEX_CONTRIBUTIONS_STATSD",
+ "RELEASE_APEX_CONTRIBUTIONS_UWB",
+ "RELEASE_APEX_CONTRIBUTIONS_WIFI",
+ }
+)
+
+// Returns the list of _selected_ apex_contributions
+// Each mainline module will have one entry in the list
+func (c *config) AllApexContributions() []string {
+ ret := []string{}
+ for _, f := range mainlineApexContributionBuildFlags {
+ if val, exists := c.GetBuildFlag(f); exists && val != "" {
+ ret = append(ret, val)
+ }
+ }
+ return ret
+}
diff --git a/android/module.go b/android/module.go
index 250161f..0d405eb 100644
--- a/android/module.go
+++ b/android/module.go
@@ -3231,6 +3231,8 @@
return true
} else if tag == licensesTag {
return true
+ } else if tag == acDepTag {
+ return true
}
return false
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index e7b7979..91c0aa1 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -387,7 +387,7 @@
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
- ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
+ ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
}
@@ -406,6 +406,8 @@
// PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
// corresponding source module, if one exists for the same variant.
+// Add a dependency from the prebuilt to `all_apex_contributions`
+// The metadata will be used for source vs prebuilts selection
func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
m := ctx.Module()
// If this module is a prebuilt, is enabled and has not been renamed to source then add a
@@ -416,6 +418,14 @@
ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
p.properties.SourceExists = true
}
+ // Add a dependency from the prebuilt to the `all_apex_contributions`
+ // metadata module
+ // TODO: When all branches contain this singleton module, make this strict
+ // TODO: Add this dependency only for mainline prebuilts and not every prebuilt module
+ if ctx.OtherModuleExists("all_apex_contributions") {
+ ctx.AddDependency(m, acDepTag, "all_apex_contributions")
+ }
+
}
}
@@ -435,7 +445,11 @@
// PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or
// because the source module doesn't exist. It also disables installing overridden source modules.
-func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
+//
+// If the visited module is the metadata module `all_apex_contributions`, it sets a
+// provider containing metadata about whether source or prebuilt of mainline modules should be used.
+// This logic was added here to prevent the overhead of creating a new mutator.
+func PrebuiltSelectModuleMutator(ctx BottomUpMutatorContext) {
m := ctx.Module()
if p := GetEmbeddedPrebuilt(m); p != nil {
if p.srcsSupplier == nil && p.srcsPropertyName == "" {
@@ -444,6 +458,17 @@
if !p.properties.SourceExists {
p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil, m)
}
+ // Propagate the provider received from `all_apex_contributions`
+ // to the source module
+ ctx.VisitDirectDepsWithTag(acDepTag, func(am Module) {
+ if ctx.Config().Bp2buildMode() {
+ // This provider key is not applicable in bp2build
+ return
+ }
+ psi := ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
+ ctx.SetProvider(PrebuiltSelectionInfoProvider, psi)
+ })
+
} else if s, ok := ctx.Module().(Module); ok {
ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) {
p := GetEmbeddedPrebuilt(prebuiltModule)
@@ -455,6 +480,11 @@
}
})
}
+ // If this is `all_apex_contributions`, set a provider containing
+ // metadata about source vs prebuilts selection
+ if am, ok := m.(*allApexContributions); ok {
+ am.SetPrebuiltSelectionInfoProvider(ctx)
+ }
}
// PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
@@ -480,9 +510,66 @@
}
}
+// A wrapper around PrebuiltSelectionInfoMap.IsSelected with special handling for java_sdk_library
+// java_sdk_library is a macro that creates
+// 1. top-level impl library
+// 2. stub libraries (suffixed with .stubs...)
+//
+// java_sdk_library_import is a macro that creates
+// 1. top-level "impl" library
+// 2. stub libraries (suffixed with .stubs...)
+//
+// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim
+// to provide the jar deapxed from the prebuilt apex
+//
+// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the
+// selection of the top-level "impl" library so that this hook can work
+//
+// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main
+func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool {
+ if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
+ sln := proptools.String(sdkLibrary.SdkLibraryName())
+ // This is the top-level library
+ // Do not supersede the existing prebuilts vs source selection mechanisms
+ if sln == m.base().BaseModuleName() {
+ return false
+ }
+
+ // Stub library created by java_sdk_library_import
+ if p := GetEmbeddedPrebuilt(m); p != nil {
+ return psi.IsSelected(sln, PrebuiltNameFromSource(sln))
+ }
+
+ // Stub library created by java_sdk_library
+ return psi.IsSelected(sln, sln)
+ }
+ return psi.IsSelected(m.base().BaseModuleName(), m.Name())
+}
+
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
// will be used if it is marked "prefer" or if the source module is disabled.
-func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module, prebuilt Module) bool {
+func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool {
+ // Use `all_apex_contributions` for source vs prebuilt selection.
+ psi := PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(am Module) {
+ if ctx.OtherModuleHasProvider(am, PrebuiltSelectionInfoProvider) {
+ psi = ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
+ }
+ })
+
+ // If the source module is explicitly listed in the metadata module, use that
+ if source != nil && isSelected(psi, source) {
+ return false
+ }
+ // If the prebuilt module is explicitly listed in the metadata module, use that
+ if isSelected(psi, prebuilt) {
+ return true
+ }
+
+ // If the baseModuleName could not be found in the metadata module,
+ // fall back to the existing source vs prebuilt selection.
+ // TODO: Drop the fallback mechanisms
+
if !ctx.Config().Bp2buildMode() {
if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
return false
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index fc47cfd..953258e 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -335,6 +335,78 @@
prebuilt: []OsType{Android, buildOS},
},
{
+ name: "apex_contributions supersedes any source preferred via use_source_config_var",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }
+ apex_contributions {
+ name: "my_mainline_module_contribution",
+ api_domain: "apexfoo",
+ // this metadata module contains prebuilt
+ contents: ["prebuilt_bar"],
+ }
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+ `,
+ preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "true",
+ },
+ }
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
+ }
+ }),
+ // use_source_config_var indicates that source should be used
+ // but this is superseded by `my_mainline_module_contribution`
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "apex_contributions supersedes any prebuilt preferred via use_source_config_var",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }
+ apex_contributions {
+ name: "my_mainline_module_contribution",
+ api_domain: "apexfoo",
+ // this metadata module contains source
+ contents: ["bar"],
+ }
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+ `,
+ preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "false",
+ },
+ }
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
+ }
+ }),
+ // use_source_config_var indicates that prebuilt should be used
+ // but this is superseded by `my_mainline_module_contribution`
+ prebuilt: nil,
+ },
+ {
name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
modules: `
source {
@@ -497,7 +569,7 @@
}
}
-func testPrebuiltError(t *testing.T, expectedError, bp string) {
+func testPrebuiltErrorWithFixture(t *testing.T, expectedError, bp string, fixture FixturePreparer) {
t.Helper()
fs := MockFS{
"prebuilt_file": nil,
@@ -508,9 +580,15 @@
PrepareForTestWithOverrides,
fs.AddToFixture(),
FixtureRegisterWithContext(registerTestPrebuiltModules),
+ OptionalFixturePreparer(fixture),
).
ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(expectedError)).
RunTestWithBp(t, bp)
+
+}
+
+func testPrebuiltError(t *testing.T, expectedError, bp string) {
+ testPrebuiltErrorWithFixture(t, expectedError, bp, nil)
}
func TestPrebuiltShouldNotChangePartition(t *testing.T) {
@@ -559,6 +637,7 @@
ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
+ RegisterApexContributionsBuildComponents(ctx)
}
type prebuiltModule struct {
@@ -653,3 +732,33 @@
InitOverrideModule(m)
return m
}
+
+func TestPrebuiltErrorCannotListBothSourceAndPrebuiltInContributions(t *testing.T) {
+ selectMainlineModuleContritbutions := GroupFixturePreparers(
+ FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_apex_contributions",
+ }
+ }),
+ )
+ testPrebuiltErrorWithFixture(t, `Cannot use Soong module: prebuilt_foo from apex_contributions: my_apex_contributions because it has been added previously as: foo from apex_contributions: my_apex_contributions`, `
+ source {
+ name: "foo",
+ }
+ prebuilt {
+ name: "foo",
+ srcs: ["prebuilt_file"],
+ }
+ apex_contributions {
+ name: "my_apex_contributions",
+ api_domain: "my_mainline_module",
+ contents: [
+ "foo",
+ "prebuilt_foo",
+ ],
+ }
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+ `, selectMainlineModuleContritbutions)
+}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 21f0bab..82f8a4d 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1068,6 +1068,137 @@
})
}
+// If a module is listed in `mainline_module_contributions, it should be used
+// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute
+func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
+ bp := `
+ apex_contributions {
+ name: "my_mainline_module_contributions",
+ api_domain: "my_mainline_module",
+ contents: [
+ // legacy mechanism prefers the prebuilt
+ // mainline_module_contributions supersedes this since source is listed explicitly
+ "sdklib.prebuilt_preferred_using_legacy_flags",
+
+ // legacy mechanism prefers the source
+ // mainline_module_contributions supersedes this since prebuilt is listed explicitly
+ "prebuilt_sdklib.source_preferred_using_legacy_flags",
+ ],
+ }
+ all_apex_contributions {
+ name: "all_apex_contributions",
+ }
+ java_sdk_library {
+ name: "sdklib.prebuilt_preferred_using_legacy_flags",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ }
+ }
+ java_sdk_library_import {
+ name: "sdklib.prebuilt_preferred_using_legacy_flags",
+ prefer: true, // prebuilt is preferred using legacy mechanism
+ public: {
+ jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "current.txt",
+ removed_api: "removed.txt",
+ annotations: "annotations.zip",
+ },
+ system: {
+ jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "current.txt",
+ removed_api: "removed.txt",
+ annotations: "annotations.zip",
+ },
+ }
+ java_sdk_library {
+ name: "sdklib.source_preferred_using_legacy_flags",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ }
+ }
+ java_sdk_library_import {
+ name: "sdklib.source_preferred_using_legacy_flags",
+ prefer: false, // source is preferred using legacy mechanism
+ public: {
+ jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "current.txt",
+ removed_api: "removed.txt",
+ annotations: "annotations.zip",
+ },
+ system: {
+ jars: ["a.jar"],
+ stub_srcs: ["a.java"],
+ current_api: "current.txt",
+ removed_api: "removed.txt",
+ annotations: "annotations.zip",
+ },
+ }
+
+ // rdeps
+ java_library {
+ name: "public",
+ srcs: ["a.java"],
+ libs: [
+ // this should get source since source is listed in my_mainline_module_contributions
+ "sdklib.prebuilt_preferred_using_legacy_flags.stubs",
+ "sdklib.prebuilt_preferred_using_legacy_flags.stubs.system",
+
+ // this should get prebuilt since source is listed in my_mainline_module_contributions
+ "sdklib.source_preferred_using_legacy_flags.stubs",
+ "sdklib.source_preferred_using_legacy_flags.stubs.system",
+
+ ],
+ }
+ `
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"),
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ android.RegisterApexContributionsBuildComponents(ctx)
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions",
+ }
+ }),
+ ).RunTestWithBp(t, bp)
+
+ // Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
+ public := result.ModuleForTests("public", "android_common")
+ rule := public.Output("javac/public.jar")
+ inputs := rule.Implicits.Strings()
+ expectedInputs := []string{
+ // source
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar",
+ "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar",
+
+ // prebuilt
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
+ "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
+ }
+ for _, expected := range expectedInputs {
+ if !android.InList(expected, inputs) {
+ t.Errorf("expected %q to contain %q", inputs, expected)
+ }
+ }
+}
+
func TestJavaSdkLibraryEnforce(t *testing.T) {
partitionToBpOption := func(partition string) string {
switch partition {