diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 39 | ||||
| -rw-r--r-- | java/android_manifest.go | 15 | ||||
| -rwxr-xr-x | java/app.go | 11 | ||||
| -rw-r--r-- | java/droidstubs.go | 4 | ||||
| -rw-r--r-- | java/java.go | 40 | ||||
| -rw-r--r-- | java/java_test.go | 36 | ||||
| -rw-r--r-- | java/rro.go | 8 | ||||
| -rw-r--r-- | java/sdk_library.go | 3 | ||||
| -rw-r--r-- | java/testing.go | 144 |
9 files changed, 219 insertions, 81 deletions
diff --git a/java/aar.go b/java/aar.go index 44496dc57..e53653a92 100644 --- a/java/aar.go +++ b/java/aar.go @@ -301,23 +301,29 @@ var extractAssetsRule = pctx.AndroidStaticRule("extractAssets", CommandDeps: []string{"${config.Zip2ZipCmd}"}, }) -func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext, - classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string, - enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) { +type aaptBuildActionOptions struct { + sdkContext android.SdkContext + classLoaderContexts dexpreopt.ClassLoaderContextMap + excludedLibs []string + enforceDefaultTargetSdkVersion bool + extraLinkFlags []string +} + +func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) { staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags := - aaptLibs(ctx, sdkContext, classLoaderContexts) + aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts) // Exclude any libraries from the supplied list. - classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs) + opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs) // App manifest file manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{ - SdkContext: sdkContext, - ClassLoaderContexts: classLoaderContexts, + SdkContext: opts.sdkContext, + ClassLoaderContexts: opts.classLoaderContexts, IsLibrary: a.isLibrary, DefaultManifestVersion: a.defaultManifestVersion, UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs, @@ -325,7 +331,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon UseEmbeddedDex: a.useEmbeddedDex, HasNoCode: a.hasNoCode, LoggingParent: a.LoggingParent, - EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion, + EnforceDefaultTargetSdkVersion: opts.enforceDefaultTargetSdkVersion, }) staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList()) @@ -341,7 +347,10 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...) if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) { - a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary) + manifestMergerParams := ManifestMergerParams{ + staticLibManifests: transitiveManifestPaths[1:], + isLibrary: a.isLibrary} + a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams) if !a.isLibrary { // Only use the merged manifest for applications. For libraries, the transitive closure of manifests // will be propagated to the final application and merged there. The merged manifest for libraries is @@ -352,12 +361,12 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon a.mergedManifestFile = manifestPath } - compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath) + compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, opts.sdkContext, manifestPath) linkFlags = append(linkFlags, libFlags...) linkDeps = append(linkDeps, sharedDeps...) linkDeps = append(linkDeps, staticDeps.resPackages()...) - linkFlags = append(linkFlags, extraLinkFlags...) + linkFlags = append(linkFlags, opts.extraLinkFlags...) if a.isLibrary { linkFlags = append(linkFlags, "--static-lib") } @@ -729,7 +738,13 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.aapt.isLibrary = true a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) - a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil, false) + a.aapt.buildActions(ctx, + aaptBuildActionOptions{ + sdkContext: android.SdkContext(a), + classLoaderContexts: a.classLoaderContexts, + enforceDefaultTargetSdkVersion: false, + }, + ) a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() diff --git a/java/android_manifest.go b/java/android_manifest.go index f2ebfa6a2..a39c00251 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -200,11 +200,16 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, return fixedManifest.WithoutRel() } -func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths, - isLibrary bool) android.Path { +type ManifestMergerParams struct { + staticLibManifests android.Paths + isLibrary bool +} + +func manifestMerger(ctx android.ModuleContext, manifest android.Path, + params ManifestMergerParams) android.Path { var args string - if !isLibrary { + if !params.isLibrary { // Follow Gradle's behavior, only pass --remove-tools-declarations when merging app manifests. args = "--remove-tools-declarations" } @@ -214,10 +219,10 @@ func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibM Rule: manifestMergerRule, Description: "merge manifest", Input: manifest, - Implicits: staticLibManifests, + Implicits: params.staticLibManifests, Output: mergedManifest, Args: map[string]string{ - "libs": android.JoinWithPrefix(staticLibManifests.Strings(), "--libs "), + "libs": android.JoinWithPrefix(params.staticLibManifests.Strings(), "--libs "), "args": args, }, }) diff --git a/java/app.go b/java/app.go index 166c22d94..ce94ababd 100755 --- a/java/app.go +++ b/java/app.go @@ -481,8 +481,15 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { if a.Updatable() { a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion } - a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, - a.usesLibraryProperties.Exclude_uses_libs, a.enforceDefaultTargetSdkVersion(), aaptLinkFlags...) + a.aapt.buildActions(ctx, + aaptBuildActionOptions{ + android.SdkContext(a), + a.classLoaderContexts, + a.usesLibraryProperties.Exclude_uses_libs, + a.enforceDefaultTargetSdkVersion(), + aaptLinkFlags, + }, + ) // apps manifests are handled by aapt, don't let Module see them a.properties.Manifest = nil diff --git a/java/droidstubs.go b/java/droidstubs.go index b059c0abf..5432ce7f5 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -538,7 +538,9 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi // Force metalava to sort overloaded methods by their order in the source code. // See b/285312164 for more information. - cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source") + // And add concrete overrides of abstract methods, see b/299366704 for more + // information. + cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source,add-additional-overrides=yes") if ctx.DeviceConfig().HideFlaggedApis() { cmd.FlagWithArg("--hide-annotation ", "android.annotation.FlaggedApi") diff --git a/java/java.go b/java/java.go index cac49a2c5..35fd7c2b8 100644 --- a/java/java.go +++ b/java/java.go @@ -1087,6 +1087,10 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } +func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { + return ctx.DeviceConfig().NativeCoverageEnabled() +} + func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { if len(j.testHostProperties.Data_device_bins_first) > 0 { deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() @@ -1689,6 +1693,12 @@ type JavaApiLibraryProperties struct { // Version of previously released API file for compatibility check. Previous_api *string `android:"path"` + + // java_system_modules module providing the jar to be added to the + // bootclasspath when compiling the stubs. + // The jar will also be passed to metalava as a classpath to + // generate compilable stubs. + System_modules *string } func ApiLibraryFactory() android.Module { @@ -1708,7 +1718,8 @@ func (al *ApiLibrary) StubsJar() android.Path { } func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, - srcs android.Paths, homeDir android.WritablePath) *android.RuleBuilderCommand { + srcs android.Paths, homeDir android.WritablePath, + classpath android.Paths) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -1747,12 +1758,17 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("--hide ", "InvalidNullabilityOverride"). FlagWithArg("--hide ", "ChangedDefault") - // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore - // classes on the classpath when an API file contains missing classes. However, as this command - // does not specify `--classpath` this is not needed for that. However, this is also used as a - // signal to the special metalava code for generating stubs from text files that it needs to add - // some additional items into the API (e.g. default constructors). - cmd.FlagWithArg("--api-class-resolution ", "api") + if len(classpath) == 0 { + // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore + // classes on the classpath when an API file contains missing classes. However, as this command + // does not specify `--classpath` this is not needed for that. However, this is also used as a + // signal to the special metalava code for generating stubs from text files that it needs to add + // some additional items into the API (e.g. default constructors). + cmd.FlagWithArg("--api-class-resolution ", "api") + } else { + cmd.FlagWithArg("--api-class-resolution ", "api:classpath") + cmd.FlagWithInputList("--classpath ", classpath, ":") + } return cmd } @@ -1815,6 +1831,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { if al.properties.Full_api_surface_stub != nil { ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub)) } + if al.properties.System_modules != nil { + ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules)) + } } // Map where key is the api scope name and value is the int value @@ -1854,6 +1873,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { var classPaths android.Paths var staticLibs android.Paths var depApiSrcsStubsJar android.Path + var systemModulesPaths android.Paths ctx.VisitDirectDeps(func(dep android.Module) { tag := ctx.OtherModuleDependencyTag(dep) switch tag { @@ -1872,6 +1892,9 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { case depApiSrcsTag: provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) depApiSrcsStubsJar = provider.HeaderJars[0] + case systemModulesTag: + module := dep.(SystemModulesProvider) + systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) } }) @@ -1885,7 +1908,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) } - cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir) + cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths) al.stubsFlags(ctx, cmd, stubsDir) @@ -1917,6 +1940,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { flags.javaVersion = getStubsJavaVersion() flags.javacFlags = strings.Join(al.properties.Javacflags, " ") flags.classpath = classpath(classPaths) + flags.bootClasspath = classpath(systemModulesPaths) annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") diff --git a/java/java_test.go b/java/java_test.go index d51604a25..6b8b735f7 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2447,3 +2447,39 @@ func TestJavaApiLibraryApiFilesSorting(t *testing.T) { "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt" android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag) } + +func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + android.FixtureModifyConfig(func(config android.Config) { + config.SetApiLibraries([]string{"foo"}) + }), + android.FixtureMergeMockFs( + map[string][]byte{ + "A.java": nil, + }, + ), + ).RunTestWithBp(t, ` + java_library { + name: "bar", + srcs: ["a.java"], + } + java_system_modules { + name: "baz", + libs: ["bar"], + } + java_sdk_library { + name: "foo", + srcs: ["A.java"], + system_modules: "baz", + } + `) + m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") + manifest := m.Output("metalava.sbox.textproto") + sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) + manifestCommand := sboxProto.Commands[0].GetCommand() + classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar" + android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag) +} diff --git a/java/rro.go b/java/rro.go index 53faca069..3e0f8e94d 100644 --- a/java/rro.go +++ b/java/rro.go @@ -146,7 +146,13 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC aaptLinkFlags = append(aaptLinkFlags, "--rename-overlay-category "+*r.overridableProperties.Category) } - r.aapt.buildActions(ctx, r, nil, nil, false, aaptLinkFlags...) + r.aapt.buildActions(ctx, + aaptBuildActionOptions{ + sdkContext: r, + enforceDefaultTargetSdkVersion: false, + extraLinkFlags: aaptLinkFlags, + }, + ) // Sign the built package _, _, certificates := collectAppDeps(ctx, r, false, false) diff --git a/java/sdk_library.go b/java/sdk_library.go index e410a41fa..f72c6086f 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1837,6 +1837,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, Libs []string Static_libs []string Full_api_surface_stub *string + System_modules *string }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) @@ -1875,6 +1876,8 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") } + props.System_modules = module.deviceProperties.System_modules + mctx.CreateModule(ApiLibraryFactory, &props) } diff --git a/java/testing.go b/java/testing.go index 98bea7f14..446135116 100644 --- a/java/testing.go +++ b/java/testing.go @@ -73,10 +73,15 @@ var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers( // Needed for various deps defined in GatherRequiredDepsForTest() defaultJavaDir + "/a.java": nil, defaultJavaDir + "/api/current.txt": nil, + defaultJavaDir + "/api/removed.txt": nil, defaultJavaDir + "/api/system-current.txt": nil, + defaultJavaDir + "/api/system-removed.txt": nil, defaultJavaDir + "/api/test-current.txt": nil, + defaultJavaDir + "/api/test-removed.txt": nil, defaultJavaDir + "/api/module-lib-current.txt": nil, + defaultJavaDir + "/api/module-lib-removed.txt": nil, defaultJavaDir + "/api/system-server-current.txt": nil, + defaultJavaDir + "/api/system-server-removed.txt": nil, // Needed for R8 rules on apps "build/make/core/proguard.flags": nil, @@ -410,6 +415,7 @@ func gatherRequiredDepsForTest() string { "stub-annotations", "aconfig-annotations-lib", + "unsupportedappusage", } for _, extra := range extraModules { @@ -424,80 +430,96 @@ func gatherRequiredDepsForTest() string { `, extra) } - type apiContributionStruct struct { - name string - apiSurface string - apiFile string + type droidstubsStruct struct { + name string + apiSurface string + apiFile string + removedFile string } - var publicApiContribution = apiContributionStruct{ - name: "api-stubs-docs-non-updatable.api.contribution", - apiSurface: "public", - apiFile: "api/current.txt", + var publicDroidstubs = droidstubsStruct{ + name: "api-stubs-docs-non-updatable", + apiSurface: "public", + apiFile: "api/current.txt", + removedFile: "api/removed.txt", } - var systemApiContribution = apiContributionStruct{ - name: "system-api-stubs-docs-non-updatable.api.contribution", - apiSurface: "system", - apiFile: "api/system-current.txt", + var systemDroidstubs = droidstubsStruct{ + name: "system-api-stubs-docs-non-updatable", + apiSurface: "system", + apiFile: "api/system-current.txt", + removedFile: "api/system-removed.txt", } - var testApiContribution = apiContributionStruct{ - name: "test-api-stubs-docs-non-updatable.api.contribution", - apiSurface: "test", - apiFile: "api/test-current.txt", + var testDroidstubs = droidstubsStruct{ + name: "test-api-stubs-docs-non-updatable", + apiSurface: "test", + apiFile: "api/test-current.txt", + removedFile: "api/test-removed.txt", } - var moduleLibApiContribution = apiContributionStruct{ - name: "module-lib-api-stubs-docs-non-updatable.api.contribution", - apiSurface: "module-lib", - apiFile: "api/module-lib-current.txt", + var moduleLibDroidstubs = droidstubsStruct{ + name: "module-lib-api-stubs-docs-non-updatable", + apiSurface: "module-lib", + apiFile: "api/module-lib-current.txt", + removedFile: "api/module-lib-removed.txt", } - var systemServerApiContribution = apiContributionStruct{ + var systemServerDroidstubs = droidstubsStruct{ // This module does not exist but is named this way for consistency - name: "system-server-api-stubs-docs-non-updatable.api.contribution", - apiSurface: "system-server", - apiFile: "api/system-server-current.txt", + name: "system-server-api-stubs-docs-non-updatable", + apiSurface: "system-server", + apiFile: "api/system-server-current.txt", + removedFile: "api/system-server-removed.txt", } - var apiContributionStructs = []apiContributionStruct{ - publicApiContribution, - systemApiContribution, - testApiContribution, - moduleLibApiContribution, - systemServerApiContribution, + var droidstubsStructs = []droidstubsStruct{ + publicDroidstubs, + systemDroidstubs, + testDroidstubs, + moduleLibDroidstubs, + systemServerDroidstubs, } - extraApiLibraryModules := map[string]apiContributionStruct{ - "android_stubs_current.from-text": publicApiContribution, - "android_system_stubs_current.from-text": systemApiContribution, - "android_test_stubs_current.from-text": testApiContribution, - "android_module_lib_stubs_current.from-text": moduleLibApiContribution, - "android_module_lib_stubs_current_full.from-text": moduleLibApiContribution, - "android_system_server_stubs_current.from-text": systemServerApiContribution, - "core.current.stubs.from-text": publicApiContribution, - "legacy.core.platform.api.stubs.from-text": publicApiContribution, - "stable.core.platform.api.stubs.from-text": publicApiContribution, - "core-lambda-stubs.from-text": publicApiContribution, - "android-non-updatable.stubs.from-text": publicApiContribution, - "android-non-updatable.stubs.system.from-text": systemApiContribution, - "android-non-updatable.stubs.test.from-text": testApiContribution, - "android-non-updatable.stubs.module_lib.from-text": moduleLibApiContribution, + extraApiLibraryModules := map[string]droidstubsStruct{ + "android_stubs_current.from-text": publicDroidstubs, + "android_system_stubs_current.from-text": systemDroidstubs, + "android_test_stubs_current.from-text": testDroidstubs, + "android_module_lib_stubs_current.from-text": moduleLibDroidstubs, + "android_module_lib_stubs_current_full.from-text": moduleLibDroidstubs, + "android_system_server_stubs_current.from-text": systemServerDroidstubs, + "core.current.stubs.from-text": publicDroidstubs, + "legacy.core.platform.api.stubs.from-text": publicDroidstubs, + "stable.core.platform.api.stubs.from-text": publicDroidstubs, + "core-lambda-stubs.from-text": publicDroidstubs, + "android-non-updatable.stubs.from-text": publicDroidstubs, + "android-non-updatable.stubs.system.from-text": systemDroidstubs, + "android-non-updatable.stubs.test.from-text": testDroidstubs, + "android-non-updatable.stubs.module_lib.from-text": moduleLibDroidstubs, } - for _, apiContribution := range apiContributionStructs { + for _, droidstubs := range droidstubsStructs { bp += fmt.Sprintf(` - java_api_contribution { + droidstubs { name: "%s", api_surface: "%s", - api_file: "%s", + check_api: { + current: { + api_file: "%s", + removed_api_file: "%s", + } + } } - `, apiContribution.name, apiContribution.apiSurface, apiContribution.apiFile) + `, + droidstubs.name, + droidstubs.apiSurface, + droidstubs.apiFile, + droidstubs.removedFile, + ) } - for libName, apiContribution := range extraApiLibraryModules { + for libName, droidstubs := range extraApiLibraryModules { bp += fmt.Sprintf(` java_api_library { name: "%s", api_contributions: ["%s"], } - `, libName, apiContribution.name) + `, libName, droidstubs.name+".api.contribution") } bp += ` @@ -552,7 +574,7 @@ func gatherRequiredDepsForTest() string { return bp } -func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { +func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string) []string { t.Helper() module := ctx.ModuleForTests(name, variant).Module() deps := []string{} @@ -561,11 +583,29 @@ func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, varia }) sort.Strings(deps) + return deps +} + +// CheckModuleDependencies checks if the expected dependencies of the module are +// identical to the actual dependencies. +func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { + deps := getModuleDependencies(t, ctx, name, variant) + if actual := deps; !reflect.DeepEqual(expected, actual) { t.Errorf("expected %#q, found %#q", expected, actual) } } +// CheckModuleHasDependency returns true if the module depends on the expected dependency. +func CheckModuleHasDependency(t *testing.T, ctx *android.TestContext, name, variant string, expected string) bool { + for _, dep := range getModuleDependencies(t, ctx, name, variant) { + if dep == expected { + return true + } + } + return false +} + // CheckPlatformBootclasspathModules returns the apex:module pair for the modules depended upon by // the platform-bootclasspath module. func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) { |