diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/Android.bp | 1 | ||||
-rw-r--r-- | java/aar.go | 8 | ||||
-rw-r--r-- | java/app_import.go | 3 | ||||
-rw-r--r-- | java/app_import_test.go | 91 | ||||
-rw-r--r-- | java/app_set.go | 2 | ||||
-rw-r--r-- | java/base.go | 33 | ||||
-rw-r--r-- | java/bootclasspath.go | 8 | ||||
-rw-r--r-- | java/bootclasspath_fragment.go | 6 | ||||
-rw-r--r-- | java/config/config.go | 1 | ||||
-rw-r--r-- | java/core-libraries/Android.bp | 168 | ||||
-rw-r--r-- | java/dexpreopt.go | 8 | ||||
-rw-r--r-- | java/dexpreopt_bootjars.go | 48 | ||||
-rw-r--r-- | java/droidstubs.go | 30 | ||||
-rw-r--r-- | java/jarjar_test.go | 85 | ||||
-rw-r--r-- | java/java.go | 185 | ||||
-rw-r--r-- | java/java_test.go | 76 | ||||
-rw-r--r-- | java/jdeps_test.go | 38 | ||||
-rw-r--r-- | java/metalava/Android.bp | 18 | ||||
-rw-r--r-- | java/metalava/OWNERS | 3 | ||||
-rw-r--r-- | java/metalava/main-config.xml | 19 | ||||
-rw-r--r-- | java/metalava/source-model-selection-config.xml | 19 | ||||
-rw-r--r-- | java/ravenwood.go | 43 | ||||
-rw-r--r-- | java/ravenwood_test.go | 14 | ||||
-rw-r--r-- | java/sdk_library.go | 156 | ||||
-rw-r--r-- | java/sdk_library_test.go | 36 | ||||
-rw-r--r-- | java/testing.go | 30 |
26 files changed, 607 insertions, 522 deletions
diff --git a/java/Android.bp b/java/Android.bp index a941754db..9603815a1 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -101,6 +101,7 @@ bootstrap_go_package { "hiddenapi_singleton_test.go", "jacoco_test.go", "java_test.go", + "jarjar_test.go", "jdeps_test.go", "kotlin_test.go", "lint_test.go", diff --git a/java/aar.go b/java/aar.go index 4a60f908a..93ff7dd97 100644 --- a/java/aar.go +++ b/java/aar.go @@ -76,7 +76,7 @@ type aaptProperties struct { // list of directories relative to the Blueprints file containing // Android resources. Defaults to ["res"] if a directory called res exists. // Set to [] to disable the default. - Resource_dirs []string + Resource_dirs []string `android:"path"` // list of zip files containing Android resources. Resource_zips []string `android:"path"` @@ -166,7 +166,11 @@ func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) { func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool { return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) && // TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries. - !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") + !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") && + // Use the legacy resource processor in kythe builds. + // The legacy resource processor creates an R.srcjar, which kythe can use for generating crossrefs. + // TODO(b/354854007): Re-enable BusyBox in kythe builds + !ctx.Config().EmitXrefRules() } func (a *aapt) filterProduct() string { diff --git a/java/app_import.go b/java/app_import.go index fa87997cf..045a89a34 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -431,6 +431,9 @@ func (a *AndroidAppImport) validatePresignedApk(ctx android.ModuleContext, srcAp var extraArgs []string if a.Privileged() { extraArgs = append(extraArgs, "--privileged") + if ctx.Config().UncompressPrivAppDex() { + extraArgs = append(extraArgs, "--uncompress-priv-app-dex") + } } if proptools.Bool(a.properties.Skip_preprocessed_apk_checks) { extraArgs = append(extraArgs, "--skip-preprocessed-apk-checks") diff --git a/java/app_import_test.go b/java/app_import_test.go index 496fc1308..54a5e7518 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -777,30 +777,79 @@ func TestAndroidTestImport_Preprocessed(t *testing.T) { } func TestAndroidAppImport_Preprocessed(t *testing.T) { - ctx, _ := testJava(t, ` - android_app_import { - name: "foo", - apk: "prebuilts/apk/app.apk", - presigned: true, - preprocessed: true, - } - `) + for _, dontUncompressPrivAppDexs := range []bool{false, true} { + name := fmt.Sprintf("dontUncompressPrivAppDexs:%t", dontUncompressPrivAppDexs) + t.Run(name, func(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.UncompressPrivAppDex = proptools.BoolPtr(!dontUncompressPrivAppDexs) + }), + ).RunTestWithBp(t, ` + android_app_import { + name: "foo", + apk: "prebuilts/apk/app.apk", + presigned: true, + preprocessed: true, + } - apkName := "foo.apk" - variant := ctx.ModuleForTests("foo", "android_common") - outputBuildParams := variant.Output(apkName).BuildParams - if outputBuildParams.Rule.String() != android.Cp.String() { - t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String()) - } + android_app_import { + name: "bar", + apk: "prebuilts/apk/app.apk", + presigned: true, + privileged: true, + preprocessed: true, + } + `) + + // non-privileged app + apkName := "foo.apk" + variant := result.ModuleForTests("foo", "android_common") + outputBuildParams := variant.Output(apkName).BuildParams + if outputBuildParams.Rule.String() != android.Cp.String() { + t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String()) + } - // Make sure compression and aligning were validated. - if outputBuildParams.Validation == nil { - t.Errorf("Expected validation rule, but was not found") - } + // Make sure compression and aligning were validated. + if outputBuildParams.Validation == nil { + t.Errorf("Expected validation rule, but was not found") + } + + validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams + if validationBuildParams.Rule.String() != checkPresignedApkRule.String() { + t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String()) + } - validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams - if validationBuildParams.Rule.String() != checkPresignedApkRule.String() { - t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String()) + expectedScriptArgs := "--preprocessed" + actualScriptArgs := validationBuildParams.Args["extraArgs"] + android.AssertStringEquals(t, "check script extraArgs", expectedScriptArgs, actualScriptArgs) + + // privileged app + apkName = "bar.apk" + variant = result.ModuleForTests("bar", "android_common") + outputBuildParams = variant.Output(apkName).BuildParams + if outputBuildParams.Rule.String() != android.Cp.String() { + t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String()) + } + + // Make sure compression and aligning were validated. + if outputBuildParams.Validation == nil { + t.Errorf("Expected validation rule, but was not found") + } + + validationBuildParams = variant.Output("validated-prebuilt/check.stamp").BuildParams + if validationBuildParams.Rule.String() != checkPresignedApkRule.String() { + t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String()) + } + + expectedScriptArgs = "--privileged" + if !dontUncompressPrivAppDexs { + expectedScriptArgs += " --uncompress-priv-app-dex" + } + expectedScriptArgs += " --preprocessed" + actualScriptArgs = validationBuildParams.Args["extraArgs"] + android.AssertStringEquals(t, "check script extraArgs", expectedScriptArgs, actualScriptArgs) + }) } } diff --git a/java/app_set.go b/java/app_set.go index 33d3adec2..7997570aa 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -35,7 +35,7 @@ func RegisterAppSetBuildComponents(ctx android.RegistrationContext) { type AndroidAppSetProperties struct { // APK Set path - Set *string + Set *string `android:"path"` // Specifies that this app should be installed to the priv-app directory, // where the system will grant it additional privileges not available to diff --git a/java/base.go b/java/base.go index 44bc75946..ba4a72912 100644 --- a/java/base.go +++ b/java/base.go @@ -91,6 +91,10 @@ type CommonProperties struct { // if not blank, run jarjar using the specified rules file Jarjar_rules *string `android:"path,arch_variant"` + // java class names to rename with jarjar when a reverse dependency has a jarjar_prefix + // property. + Jarjar_rename []string + // if not blank, used as prefix to generate repackage rule Jarjar_prefix *string @@ -550,6 +554,10 @@ type Module struct { // java_aconfig_library or java_library modules that are statically linked // to this module. Does not contain cache files from all transitive dependencies. aconfigCacheFiles android.Paths + + // List of soong module dependencies required to compile the current module. + // This information is printed out to `Dependencies` field in module_bp_java_deps.json + compileDepNames []string } var _ android.InstallableModule = (*Module)(nil) @@ -2054,10 +2062,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { } func (j *Module) CompilerDeps() []string { - jdeps := []string{} - jdeps = append(jdeps, j.properties.Libs...) - jdeps = append(jdeps, j.properties.Static_libs...) - return jdeps + return j.compileDepNames } func (j *Module) hasCode(ctx android.ModuleContext) bool { @@ -2401,6 +2406,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } } + if android.InList(tag, compileDependencyTags) { + // Add the dependency name to compileDepNames so that it can be recorded in module_bp_java_deps.json + j.compileDepNames = append(j.compileDepNames, otherName) + } + addCLCFromDep(ctx, module, j.classLoaderContexts) addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary) }) @@ -2642,8 +2652,7 @@ func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProvi // Gather repackage information from deps result := collectDirectDepsProviders(ctx) - // Update that with entries we've stored for ourself - for orig, renamed := range module.jarjarRenameRules { + add := func(orig string, renamed string) { if result == nil { result = &JarJarProviderData{ Rename: make(map[string]string), @@ -2652,12 +2661,22 @@ func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProvi if renamed != "" { if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed { ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting) - continue + return } } (*result).Rename[orig] = renamed } + // Update that with entries we've stored for ourself + for orig, renamed := range module.jarjarRenameRules { + add(orig, renamed) + } + + // Update that with entries given in the jarjar_rename property. + for _, orig := range module.properties.Jarjar_rename { + add(orig, "") + } + // If there are no renamings, then jarjar_prefix does nothing, so skip the extra work. if result == nil { return nil diff --git a/java/bootclasspath.go b/java/bootclasspath.go index 77ddf5c05..029f6f623 100644 --- a/java/bootclasspath.go +++ b/java/bootclasspath.go @@ -196,7 +196,7 @@ var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"} type BootclasspathNestedAPIProperties struct { // java_library or preferably, java_sdk_library modules providing stub classes that define the // APIs provided by this bootclasspath_fragment. - Stub_libs []string + Stub_libs proptools.Configurable[[]string] } // BootclasspathAPIProperties defines properties for defining the API provided by parts of the @@ -229,11 +229,11 @@ type BootclasspathAPIProperties struct { // apiScopeToStubLibs calculates the stub library modules for each relevant *HiddenAPIScope from the // Stub_libs properties. -func (p BootclasspathAPIProperties) apiScopeToStubLibs() map[*HiddenAPIScope][]string { +func (p BootclasspathAPIProperties) apiScopeToStubLibs(ctx android.BaseModuleContext) map[*HiddenAPIScope][]string { m := map[*HiddenAPIScope][]string{} for _, apiScope := range hiddenAPISdkLibrarySupportedScopes { - m[apiScope] = p.Api.Stub_libs + m[apiScope] = p.Api.Stub_libs.GetOrDefault(ctx, nil) } - m[CorePlatformHiddenAPIScope] = p.Core_platform_api.Stub_libs + m[CorePlatformHiddenAPIScope] = p.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil) return m } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 16209b72e..bce507a7d 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -445,7 +445,7 @@ func (b *BootclasspathFragmentModule) ComponentDepsMutator(ctx android.BottomUpM func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorContext) { // Add dependencies onto all the modules that provide the API stubs for classes on this // bootclasspath fragment. - hiddenAPIAddStubLibDependencies(ctx, b.properties.apiScopeToStubLibs()) + hiddenAPIAddStubLibDependencies(ctx, b.properties.apiScopeToStubLibs(ctx)) for _, additionalStubModule := range b.properties.Additional_stubs { for _, apiScope := range hiddenAPISdkLibrarySupportedScopes { @@ -933,8 +933,8 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro b.Filtered_flags_path = android.OptionalPathForPath(hiddenAPIInfo.FilteredFlagsPath) // Copy stub_libs properties. - b.Stub_libs = module.properties.Api.Stub_libs - b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs + b.Stub_libs = module.properties.Api.Stub_libs.GetOrDefault(mctx, nil) + b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs.GetOrDefault(mctx, nil) // Copy fragment properties. b.Fragments = module.properties.Fragments diff --git a/java/config/config.go b/java/config/config.go index 2bb50f62a..66e857c64 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -47,6 +47,7 @@ var ( "services", "android.car", "android.car7", + "android.car.builtin", "conscrypt", "core-icu4j", "core-oj", diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index ab72e8b6d..cee7a192e 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -41,7 +41,7 @@ java_defaults { } java_library { - name: "core.current.stubs.from-source", + name: "core.current.stubs", defaults: [ "core.current.stubs.defaults", ], @@ -52,8 +52,12 @@ java_library { ], } +// Used for bootstrapping ART system modules java_api_library { name: "core.current.stubs.from-text", + defaults: [ + "core.current.stubs.defaults", + ], api_surface: "core", api_contributions: [ "art.module.public.api.stubs.source.api.contribution", @@ -68,27 +72,7 @@ java_api_library { } java_library { - name: "core.current.stubs", - defaults: [ - "core.current.stubs.defaults", - ], - static_libs: [ - "core.current.stubs.from-source", - ], - product_variables: { - build_from_text_stub: { - static_libs: [ - "core.current.stubs.from-text", - ], - exclude_static_libs: [ - "core.current.stubs.from-source", - ], - }, - }, -} - -java_library { - name: "core.current.stubs.exportable.from-source", + name: "core.current.stubs.exportable", defaults: [ "core.current.stubs.defaults", ], @@ -103,16 +87,6 @@ java_library { }, } -java_library { - name: "core.current.stubs.exportable", - defaults: [ - "core.current.stubs.defaults", - ], - static_libs: [ - "core.current.stubs.exportable.from-source", - ], -} - // Distributed with the SDK for turning into system modules to compile apps // against. // @@ -201,26 +175,6 @@ java_library { "core.module_lib.stubs.defaults", ], static_libs: [ - "core.module_lib.stubs.from-source", - ], - product_variables: { - build_from_text_stub: { - static_libs: [ - "core.module_lib.stubs.from-text", - ], - exclude_static_libs: [ - "core.module_lib.stubs.from-source", - ], - }, - }, -} - -java_library { - name: "core.module_lib.stubs.from-source", - defaults: [ - "core.module_lib.stubs.defaults", - ], - static_libs: [ "art.module.public.api.stubs.module_lib", // Replace the following with the module-lib correspondence when Conscrypt or i18N module @@ -231,27 +185,6 @@ java_library { ], } -java_api_library { - name: "core.module_lib.stubs.from-text", - api_surface: "module-lib", - api_contributions: [ - "art.module.public.api.stubs.source.api.contribution", - "art.module.public.api.stubs.source.system.api.contribution", - "art.module.public.api.stubs.source.module_lib.api.contribution", - - // Add the module-lib correspondence when Conscrypt or i18N module - // provides @SystemApi(MODULE_LIBRARIES). Currently, assume that only ART module provides - // @SystemApi(MODULE_LIBRARIES). - "conscrypt.module.public.api.stubs.source.api.contribution", - "i18n.module.public.api.stubs.source.api.contribution", - ], - libs: [ - "stub-annotations", - ], - visibility: ["//visibility:private"], - stubs_type: "everything", -} - // Produces a dist file that is used by the // prebuilts/sdk/update_prebuilts.py script to update the prebuilts/sdk // directory. @@ -311,7 +244,7 @@ core_platform_visibility = ["//visibility:public"] // API annotations are available to the dex tools that enable enforcement of runtime // accessibility. b/119068555 java_library { - name: "legacy.core.platform.api.stubs.from-source", + name: "legacy.core.platform.api.stubs", visibility: core_platform_visibility, defaults: [ "core.platform.api.stubs.defaults", @@ -324,7 +257,7 @@ java_library { } java_library { - name: "legacy.core.platform.api.stubs.exportable.from-source", + name: "legacy.core.platform.api.stubs.exportable", visibility: core_platform_visibility, defaults: [ "core.platform.api.stubs.defaults", @@ -348,53 +281,6 @@ java_defaults { ], } -java_api_library { - name: "legacy.core.platform.api.stubs.from-text", - api_surface: "core_platform", - defaults: [ - "android_core_platform_stubs_current_contributions", - ], - api_contributions: [ - "legacy.i18n.module.platform.api.stubs.source.api.contribution", - ], - libs: [ - "stub-annotations", - ], - stubs_type: "everything", -} - -java_library { - name: "legacy.core.platform.api.stubs", - visibility: core_platform_visibility, - defaults: [ - "core.platform.api.stubs.defaults", - ], - static_libs: [ - "legacy.core.platform.api.stubs.from-source", - ], - product_variables: { - build_from_text_stub: { - static_libs: [ - "legacy.core.platform.api.stubs.from-text", - ], - exclude_static_libs: [ - "legacy.core.platform.api.stubs.from-source", - ], - }, - }, -} - -java_library { - name: "legacy.core.platform.api.stubs.exportable", - visibility: core_platform_visibility, - defaults: [ - "core.platform.api.stubs.defaults", - ], - static_libs: [ - "legacy.core.platform.api.stubs.exportable.from-source", - ], -} - java_defaults { name: "core.platform.api.stubs.defaults", hostdex: true, @@ -424,7 +310,7 @@ java_library { } java_library { - name: "stable.core.platform.api.stubs.from-source", + name: "stable.core.platform.api.stubs", visibility: core_platform_visibility, defaults: [ "core.platform.api.stubs.defaults", @@ -437,42 +323,6 @@ java_library { ], } -java_api_library { - name: "stable.core.platform.api.stubs.from-text", - api_surface: "core_platform", - defaults: [ - "android_core_platform_stubs_current_contributions", - ], - api_contributions: [ - "stable.i18n.module.platform.api.stubs.source.api.contribution", - ], - libs: [ - "stub-annotations", - ], - stubs_type: "everything", -} - -java_library { - name: "stable.core.platform.api.stubs", - visibility: core_platform_visibility, - defaults: [ - "core.platform.api.stubs.defaults", - ], - static_libs: [ - "stable.core.platform.api.stubs.from-source", - ], - product_variables: { - build_from_text_stub: { - static_libs: [ - "stable.core.platform.api.stubs.from-text", - ], - exclude_static_libs: [ - "stable.core.platform.api.stubs.from-source", - ], - }, - }, -} - // Same as stable.core.platform.api.stubs, but android annotations are // stripped. This is used by the Java toolchain, while the annotated stub is to // be used by Kotlin one. diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 2980babe3..a38642a50 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -616,10 +616,8 @@ func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) return installPath, relDir, installBase } -// RuleBuilder.Install() adds output-to-install copy pairs to a list for Make. To share this -// information with PackagingSpec in soong, call PackageFile for them. -// The install path and the target install partition of the module must be the same. -func packageFile(ctx android.ModuleContext, install android.RuleBuilderInstall) { +// installFile will install the file if `install` path and the target install partition are the same. +func installFile(ctx android.ModuleContext, install android.RuleBuilderInstall) { installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) // Empty name means the install partition is not for the target image. // For the system image, files for "apex" and "system_other" are skipped here. @@ -628,7 +626,7 @@ func packageFile(ctx android.ModuleContext, install android.RuleBuilderInstall) // TODO(b/320196894): Files for "system_other" are skipped because soong creates the system // image only for now. if name != "" { - ctx.PackageFile(installPath.Join(ctx, relDir), name, install.From) + ctx.InstallFile(installPath.Join(ctx, relDir), name, install.From) } } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index defa82c0c..56e007bbf 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -491,6 +491,11 @@ type dexpreoptBootJars struct { // Build path to a config file that Soong writes for Make (to be used in makefiles that install // the default boot image). dexpreoptConfigForMake android.WritablePath + + // Build path to the boot framework profile. + // This is used as the `OutputFile` in `AndroidMkEntries`. + // A non-nil value ensures that this singleton module does not get skipped in AndroidMkEntries processing. + bootFrameworkProfile android.WritablePath } func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -603,7 +608,8 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex installs := generateBootImage(ctx, config) profileInstalls = append(profileInstalls, installs...) if config == d.defaultBootImage { - _, installs := bootFrameworkProfileRule(ctx, config) + bootProfile, installs := bootFrameworkProfileRule(ctx, config) + d.bootFrameworkProfile = bootProfile profileInstalls = append(profileInstalls, installs...) } } @@ -613,7 +619,7 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex profileLicenseMetadataFile: android.OptionalPathForPath(ctx.LicenseMetadataFile()), }) for _, install := range profileInstalls { - packageFile(ctx, install) + installFile(ctx, install) } } } @@ -939,24 +945,21 @@ func packageFileForTargetImage(ctx android.ModuleContext, image *bootImageVarian } for _, install := range image.installs { - packageFile(ctx, install) + installFile(ctx, install) } for _, install := range image.vdexInstalls { - if image.target.Arch.ArchType.Name != ctx.DeviceConfig().DeviceArch() { - // Note that the vdex files are identical between architectures. If the target image is - // not for the primary architecture create symlinks to share the vdex of the primary - // architecture with the other architectures. - // - // Assuming that the install path has the architecture name with it, replace the - // architecture name with the primary architecture name to find the source vdex file. - installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) - if name != "" { - srcRelDir := strings.Replace(relDir, image.target.Arch.ArchType.Name, ctx.DeviceConfig().DeviceArch(), 1) - ctx.InstallSymlink(installPath.Join(ctx, relDir), name, installPath.Join(ctx, srcRelDir, name)) - } - } else { - packageFile(ctx, install) + installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) + if name == "" { + continue + } + // Note that the vdex files are identical between architectures. Copy the vdex to a no arch directory + // and create symlinks for both the primary and secondary arches. + ctx.InstallSymlink(installPath.Join(ctx, relDir), name, installPath.Join(ctx, "framework", name)) + if image.target.Arch.ArchType.Name == ctx.DeviceConfig().DeviceArch() { + // Copy the vdex from the primary arch to the no-arch directory + // e.g. /system/framework/$bootjar.vdex + ctx.InstallFile(installPath.Join(ctx, "framework"), name, install.From) } } } @@ -1234,7 +1237,7 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) (an profile := bootImageProfileRuleCommon(ctx, image.name, image.dexPathsDeps.Paths(), image.getAnyAndroidVariant().dexLocationsDeps) - if image == defaultBootImageConfig(ctx) { + if image == defaultBootImageConfig(ctx) && profile != nil { rule := android.NewRuleBuilder(pctx, ctx) rule.Install(profile, "/system/etc/boot-image.prof") return profile, rule.Installs() @@ -1380,3 +1383,12 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(getImageNames(), " ")) } } + +// Add one of the outputs in `OutputFile` +// This ensures that this singleton module does not get skipped when writing out/soong/Android-*.mk +func (d *dexpreoptBootJars) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(d.bootFrameworkProfile), + }} +} diff --git a/java/droidstubs.go b/java/droidstubs.go index a8e0a22e5..d6229038f 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -197,6 +197,10 @@ type DroidstubsProperties struct { // a list of aconfig_declarations module names that the stubs generated in this module // depend on. Aconfig_declarations []string + + // List of hard coded filegroups containing Metalava config files that are passed to every + // Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd. + ConfigFiles []string `android:"path" blueprint:"mutated"` } // Used by xsd_config @@ -259,6 +263,7 @@ func DroidstubsFactory() android.Module { module.AddProperties(&module.properties, &module.Javadoc.properties) + module.properties.ConfigFiles = getMetalavaConfigFilegroupReference() module.initModuleAndImport(module) InitDroiddocModule(module, android.HostAndDeviceSupported) @@ -279,6 +284,7 @@ func DroidstubsHostFactory() android.Module { module.AddProperties(&module.properties, &module.Javadoc.properties) + module.properties.ConfigFiles = getMetalavaConfigFilegroupReference() InitDroiddocModule(module, android.HostSupported) return module } @@ -694,7 +700,7 @@ func metalavaUseRbe(ctx android.ModuleContext) bool { } func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths, - srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams) *android.RuleBuilderCommand { + srcJarList android.Path, homeDir android.WritablePath, params stubsCommandConfigParams, configFiles android.Paths) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -738,9 +744,26 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs andr cmd.Flag(config.MetalavaFlags) + addMetalavaConfigFilesToCmd(cmd, configFiles) + return cmd } +// MetalavaConfigFilegroup is the name of the filegroup in build/soong/java/metalava that lists +// the configuration files to pass to Metalava. +const MetalavaConfigFilegroup = "metalava-config-files" + +// Get a reference to the MetalavaConfigFilegroup suitable for use in a property. +func getMetalavaConfigFilegroupReference() []string { + return []string{":" + MetalavaConfigFilegroup} +} + +// addMetalavaConfigFilesToCmd adds --config-file options to use the config files list in the +// MetalavaConfigFilegroup filegroup. +func addMetalavaConfigFilesToCmd(cmd *android.RuleBuilderCommand, configFiles android.Paths) { + cmd.FlagForEachInput("--config-file ", configFiles) +} + // Pass flagged apis related flags to metalava. When aconfig_declarations property is not // defined for a module, simply revert all flagged apis annotations. If aconfig_declarations // property is defined, apply transformations and only revert the flagged apis that are not @@ -812,7 +835,10 @@ func (d *Droidstubs) commonMetalavaStubCmd(ctx android.ModuleContext, rule *andr srcJarList := zipSyncCmd(ctx, rule, params.srcJarDir, d.Javadoc.srcJars) homeDir := android.PathForModuleOut(ctx, params.stubConfig.stubsType.String(), "home") - cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig) + + configFiles := android.PathsForModuleSrc(ctx, d.properties.ConfigFiles) + + cmd := metalavaCmd(ctx, rule, d.Javadoc.srcFiles, srcJarList, homeDir, params.stubConfig, configFiles) cmd.Implicits(d.Javadoc.implicits) d.stubsFlags(ctx, cmd, params.stubsDir, params.stubConfig.stubsType, params.stubConfig.checkApi) diff --git a/java/jarjar_test.go b/java/jarjar_test.go new file mode 100644 index 000000000..82bfa2b86 --- /dev/null +++ b/java/jarjar_test.go @@ -0,0 +1,85 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "fmt" + "testing" + + "android/soong/android" +) + +func AssertJarJarRename(t *testing.T, result *android.TestResult, libName, original, expectedRename string) { + module := result.ModuleForTests(libName, "android_common") + + provider, found := android.OtherModuleProvider(result.OtherModuleProviderAdaptor(), module.Module(), JarJarProvider) + android.AssertBoolEquals(t, fmt.Sprintf("found provider (%s)", libName), true, found) + + renamed, found := provider.Rename[original] + android.AssertBoolEquals(t, fmt.Sprintf("found rename (%s)", libName), true, found) + android.AssertStringEquals(t, fmt.Sprintf("renamed (%s)", libName), expectedRename, renamed) +} + +func TestJarJarRenameDifferentModules(t *testing.T) { + t.Parallel() + result := android.GroupFixturePreparers( + prepareForJavaTest, + ).RunTestWithBp(t, ` + java_library { + name: "their_lib", + jarjar_rename: ["com.example.a"], + } + + java_library { + name: "boundary_lib", + jarjar_prefix: "RENAME", + static_libs: ["their_lib"], + } + + java_library { + name: "my_lib", + static_libs: ["boundary_lib"], + } + `) + + original := "com.example.a" + renamed := "RENAME.com.example.a" + AssertJarJarRename(t, result, "their_lib", original, "") + AssertJarJarRename(t, result, "boundary_lib", original, renamed) + AssertJarJarRename(t, result, "my_lib", original, renamed) +} + +func TestJarJarRenameSameModule(t *testing.T) { + t.Parallel() + result := android.GroupFixturePreparers( + prepareForJavaTest, + ).RunTestWithBp(t, ` + java_library { + name: "their_lib", + jarjar_rename: ["com.example.a"], + jarjar_prefix: "RENAME", + } + + java_library { + name: "my_lib", + static_libs: ["their_lib"], + } + `) + + original := "com.example.a" + renamed := "RENAME.com.example.a" + AssertJarJarRename(t, result, "their_lib", original, renamed) + AssertJarJarRename(t, result, "my_lib", original, renamed) +} diff --git a/java/java.go b/java/java.go index 263d0f333..1d4fa44f2 100644 --- a/java/java.go +++ b/java/java.go @@ -269,7 +269,7 @@ type JavaInfo struct { ImplementationAndResourcesJars android.Paths // ImplementationJars is a list of jars that contain the implementations of classes in the - //module. + // module. ImplementationJars android.Paths // ResourceJars is a list of jars that contain the resources included in the module. @@ -432,7 +432,6 @@ var ( r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} javaApiContributionTag = dependencyTag{name: "java-api-contribution"} - depApiSrcsTag = dependencyTag{name: "dep-api-srcs"} aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"} jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true} binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true} @@ -443,6 +442,30 @@ var ( usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) ) +// A list of tags for deps used for compiling a module. +// Any dependency tags that modifies the following properties of `deps` in `Module.collectDeps` should be +// added to this list: +// - bootClasspath +// - classpath +// - java9Classpath +// - systemModules +// - kotlin deps... +var ( + compileDependencyTags = []blueprint.DependencyTag{ + sdkLibTag, + libTag, + staticLibTag, + bootClasspathTag, + systemModulesTag, + java9LibTag, + kotlinStdlibTag, + kotlinAnnotationsTag, + kotlinPluginTag, + syspropPublicStubDepTag, + instrumentationForTag, + } +) + func IsLibDepTag(depTag blueprint.DependencyTag) bool { return depTag == libTag || depTag == sdkLibTag } @@ -1981,12 +2004,6 @@ type JavaApiLibraryProperties struct { // merge zipped after metalava invocation Static_libs []string - // Java Api library to provide the full API surface stub jar file. - // If this property is set, the stub jar of this module is created by - // extracting the compiled class files provided by the - // full_api_surface_stub module. - Full_api_surface_stub *string - // Version of previously released API file for compatibility check. Previous_api *string `android:"path"` @@ -2015,12 +2032,26 @@ type JavaApiLibraryProperties struct { // List of aconfig_declarations module names that the stubs generated in this module // depend on. Aconfig_declarations []string + + // List of hard coded filegroups containing Metalava config files that are passed to every + // Metalava invocation that this module performs. See addMetalavaConfigFilesToCmd. + ConfigFiles []string `android:"path" blueprint:"mutated"` + + // If not blank, set to the version of the sdk to compile against. + // Defaults to an empty string, which compiles the module against the private platform APIs. + // Values are of one of the following forms: + // 1) numerical API level, "current", "none", or "core_platform" + // 2) An SDK kind with an API level: "<sdk kind>_<API level>" + // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds. + // If the SDK kind is empty, it will be set to public. + Sdk_version *string } func ApiLibraryFactory() android.Module { module := &ApiLibrary{} - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) module.AddProperties(&module.properties) + module.properties.ConfigFiles = getMetalavaConfigFilegroupReference() + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) module.initModuleAndImport(module) android.InitDefaultableModule(module) return module @@ -2036,7 +2067,7 @@ func (al *ApiLibrary) StubsJar() android.Path { func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths, homeDir android.WritablePath, - classpath android.Paths) *android.RuleBuilderCommand { + classpath android.Paths, configFiles android.Paths) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -2075,6 +2106,8 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("--hide ", "InvalidNullabilityOverride"). FlagWithArg("--hide ", "ChangedDefault") + addMetalavaConfigFilesToCmd(cmd, configFiles) + 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 @@ -2110,40 +2143,6 @@ func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.Rule } } -// This method extracts the stub class files from the stub jar file provided -// from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava. -// This method is used because metalava can generate compilable from-text stubs only when -// the codebase encompasses all classes listed in the input API text file, and a class can extend -// a class that is not within the same API domain. -func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, fullApiSurfaceStubJar android.Path) { - classFilesList := android.PathForModuleOut(ctx, "metalava", "classes.txt") - unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir") - - rule.Command(). - BuiltTool("list_files"). - Text(stubsDir.String()). - FlagWithOutput("--out ", classFilesList). - FlagWithArg("--extensions ", ".java"). - FlagWithArg("--root ", unzippedSrcJarDir.String()). - Flag("--classes") - - rule.Command(). - Text("unzip"). - Flag("-q"). - Input(fullApiSurfaceStubJar). - FlagWithArg("-d ", unzippedSrcJarDir.String()) - - rule.Command(). - BuiltTool("soong_zip"). - Flag("-jar"). - Flag("-write_if_changed"). - Flag("-ignore_missing_files"). - Flag("-quiet"). - FlagWithArg("-C ", unzippedSrcJarDir.String()). - FlagWithInput("-l ", classFilesList). - FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs) -} - func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { apiContributions := al.properties.Api_contributions addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && @@ -2170,14 +2169,18 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } } } + if ctx.Device() { + sdkDep := decodeSdkDep(ctx, android.SdkContext(al)) + if sdkDep.useModule { + ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) + ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) + ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) + + } + } ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) - 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)) - } + for _, aconfigDeclarationsName := range al.properties.Aconfig_declarations { ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfigDeclarationsName) } @@ -2233,8 +2236,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { var srcFilesInfo []JavaApiImportInfo var classPaths android.Paths + var bootclassPaths android.Paths var staticLibs android.Paths - var depApiSrcsStubsJar android.Path var systemModulesPaths android.Paths ctx.VisitDirectDeps(func(dep android.Module) { tag := ctx.OtherModuleDependencyTag(dep) @@ -2248,12 +2251,12 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { case libTag: provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) classPaths = append(classPaths, provider.HeaderJars...) + case bootClasspathTag: + provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) + bootclassPaths = append(bootclassPaths, provider.HeaderJars...) case staticLibTag: provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) staticLibs = append(staticLibs, provider.HeaderJars...) - case depApiSrcsTag: - provider, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) - depApiSrcsStubsJar = provider.HeaderJars[0] case systemModulesTag: module := dep.(SystemModulesProvider) systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) @@ -2286,7 +2289,12 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) } - cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths) + configFiles := android.PathsForModuleSrc(ctx, al.properties.ConfigFiles) + + combinedPaths := append(([]android.Path)(nil), systemModulesPaths...) + combinedPaths = append(combinedPaths, classPaths...) + combinedPaths = append(combinedPaths, bootclassPaths...) + cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, combinedPaths, configFiles) al.stubsFlags(ctx, cmd, stubsDir) @@ -2304,9 +2312,6 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) - if depApiSrcsStubsJar != nil { - al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsJar) - } rule.Command(). BuiltTool("soong_zip"). Flag("-write_if_changed"). @@ -2317,18 +2322,17 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build("metalava", "metalava merged text") - if depApiSrcsStubsJar == nil { - var flags javaBuilderFlags - flags.javaVersion = getStubsJavaVersion() - flags.javacFlags = strings.Join(al.properties.Javacflags, " ") - flags.classpath = classpath(classPaths) - flags.bootClasspath = classpath(systemModulesPaths) + javacFlags := javaBuilderFlags{ + javaVersion: getStubsJavaVersion(), + javacFlags: strings.Join(al.properties.Javacflags, " "), + classpath: classpath(classPaths), + bootClasspath: classpath(append(systemModulesPaths, bootclassPaths...)), + } - annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") + annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") - TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, - android.Paths{al.stubsSrcJar}, annoSrcJar, flags, android.Paths{}) - } + TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, + android.Paths{al.stubsSrcJar}, annoSrcJar, javacFlags, android.Paths{}) builder := android.NewRuleBuilder(pctx, ctx) builder.Command(). @@ -2340,7 +2344,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { // compile stubs to .dex for hiddenapi processing dexParams := &compileDexParams{ - flags: javaBuilderFlags{}, + flags: javacFlags, sdkVersion: al.SdkVersion(ctx), minSdkVersion: al.MinSdkVersion(ctx), classesJar: al.stubsJar, @@ -2376,19 +2380,56 @@ func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { return nil } -// java_api_library constitutes the sdk, and does not build against one +// Most java_api_library constitues the sdk, but there are some java_api_library that +// does not contribute to the api surface. Such modules are allowed to set sdk_version +// other than "none" func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return android.SdkSpecNone + return android.SdkSpecFrom(ctx, proptools.String(al.properties.Sdk_version)) } // java_api_library is always at "current". Return FutureApiLevel func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { - return android.FutureApiLevel + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) SystemModules() string { + return proptools.String(al.properties.System_modules) +} + +func (al *ApiLibrary) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return al.SdkVersion(ctx).ApiLevel +} + +func (al *ApiLibrary) IDEInfo(i *android.IdeInfo) { + i.Deps = append(i.Deps, al.ideDeps()...) + i.Libs = append(i.Libs, al.properties.Libs...) + i.Static_libs = append(i.Static_libs, al.properties.Static_libs...) + i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String()) +} + +// deps of java_api_library for module_bp_java_deps.json +func (al *ApiLibrary) ideDeps() []string { + ret := []string{} + ret = append(ret, al.properties.Libs...) + ret = append(ret, al.properties.Static_libs...) + if al.properties.System_modules != nil { + ret = append(ret, proptools.String(al.properties.System_modules)) + } + // Other non java_library dependencies like java_api_contribution are ignored for now. + return ret } // implement the following interfaces for hiddenapi processing var _ hiddenAPIModule = (*ApiLibrary)(nil) var _ UsesLibraryDependency = (*ApiLibrary)(nil) +var _ android.SdkContext = (*ApiLibrary)(nil) + +// implement the following interface for IDE completion. +var _ android.IDEInfo = (*ApiLibrary)(nil) // // Java prebuilts diff --git a/java/java_test.go b/java/java_test.go index 33079f381..2d4fca240 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1342,12 +1342,12 @@ func TestJavaLibraryWithSystemModules(t *testing.T) { } `) - checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") + checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar") - checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") + checkBootClasspathForLibWithSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar") } -func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { +func checkBootClasspathForLibWithSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) { javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac") bootClasspath := javacRule.Args["bootClasspath"] if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) { @@ -2256,61 +2256,6 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { } } -func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { - provider_bp_a := ` - java_api_contribution { - name: "foo1", - api_file: "current.txt", - api_surface: "public", - } - ` - provider_bp_b := ` - java_api_contribution { - name: "foo2", - api_file: "current.txt", - api_surface: "public", - } - ` - lib_bp_a := ` - java_api_library { - name: "lib1", - api_surface: "public", - api_contributions: ["foo1", "foo2"], - stubs_type: "everything", - } - ` - - ctx := android.GroupFixturePreparers( - prepareForJavaTest, - android.FixtureMergeMockFs( - map[string][]byte{ - "a/Android.bp": []byte(provider_bp_a), - "b/Android.bp": []byte(provider_bp_b), - "c/Android.bp": []byte(lib_bp_a), - }, - ), - android.FixtureMergeEnv( - map[string]string{ - "DISABLE_STUB_VALIDATION": "true", - }, - ), - ).RunTestWithBp(t, ` - java_api_library { - name: "bar1", - api_surface: "public", - api_contributions: ["foo1"], - full_api_surface_stub: "lib1", - stubs_type: "everything", - } - `) - - m := ctx.ModuleForTests("bar1", "android_common") - manifest := m.Output("metalava.sbox.textproto") - sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, manifest) - manifestCommand := sboxProto.Commands[0].GetCommand() - android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar") -} - func TestTransitiveSrcFiles(t *testing.T) { ctx, _ := testJava(t, ` java_library { @@ -2511,9 +2456,6 @@ func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), - android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) - }), android.FixtureMergeMockFs( map[string][]byte{ "A.java": nil, @@ -2534,12 +2476,8 @@ func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { system_modules: "baz", } `) - m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common") - manifest := m.Output("metalava.sbox.textproto") - sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest) - manifestCommand := sboxProto.Commands[0].GetCommand() - classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar" - android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag) + + checkBootClasspathForLibWithSystemModule(t, result.TestContext, apiScopePublic.apiLibraryModuleName("foo"), "/bar.jar") } func TestApiLibraryDroidstubsDependency(t *testing.T) { @@ -2547,9 +2485,6 @@ func TestApiLibraryDroidstubsDependency(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), - android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) - }), android.FixtureMergeMockFs( map[string][]byte{ "A.java": nil, @@ -2598,7 +2533,6 @@ func TestDisableFromTextStubForCoverageBuild(t *testing.T) { PrepareForTestWithJacocoInstrumentation, FixtureWithLastReleaseApis("foo"), android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) config.SetBuildFromTextStub(true) }), android.FixtureModifyEnv(func(env map[string]string) { diff --git a/java/jdeps_test.go b/java/jdeps_test.go index 874d1d7c0..e1802243c 100644 --- a/java/jdeps_test.go +++ b/java/jdeps_test.go @@ -22,28 +22,46 @@ import ( ) func TestCollectJavaLibraryPropertiesAddLibsDeps(t *testing.T) { - expected := []string{"Foo", "Bar"} - module := LibraryFactory().(*Library) - module.properties.Libs = append(module.properties.Libs, expected...) + ctx, _ := testJava(t, + ` + java_library {name: "Foo"} + java_library {name: "Bar"} + java_library { + name: "javalib", + libs: ["Foo", "Bar"], + } + `) + module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library) dpInfo := &android.IdeInfo{} module.IDEInfo(dpInfo) - if !reflect.DeepEqual(dpInfo.Deps, expected) { - t.Errorf("Library.IDEInfo() Deps = %v, want %v", dpInfo.Deps, expected) + for _, expected := range []string{"Foo", "Bar"} { + if !android.InList(expected, dpInfo.Deps) { + t.Errorf("Library.IDEInfo() Deps = %v, %v not found", dpInfo.Deps, expected) + } } } func TestCollectJavaLibraryPropertiesAddStaticLibsDeps(t *testing.T) { - expected := []string{"Foo", "Bar"} - module := LibraryFactory().(*Library) - module.properties.Static_libs = append(module.properties.Static_libs, expected...) + ctx, _ := testJava(t, + ` + java_library {name: "Foo"} + java_library {name: "Bar"} + java_library { + name: "javalib", + static_libs: ["Foo", "Bar"], + } + `) + module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library) dpInfo := &android.IdeInfo{} module.IDEInfo(dpInfo) - if !reflect.DeepEqual(dpInfo.Deps, expected) { - t.Errorf("Library.IDEInfo() Deps = %v, want %v", dpInfo.Deps, expected) + for _, expected := range []string{"Foo", "Bar"} { + if !android.InList(expected, dpInfo.Deps) { + t.Errorf("Library.IDEInfo() Deps = %v, %v not found", dpInfo.Deps, expected) + } } } diff --git a/java/metalava/Android.bp b/java/metalava/Android.bp new file mode 100644 index 000000000..ccbd191d3 --- /dev/null +++ b/java/metalava/Android.bp @@ -0,0 +1,18 @@ +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +filegroup { + name: "metalava-config-files", + srcs: ["*-config.xml"], +} diff --git a/java/metalava/OWNERS b/java/metalava/OWNERS new file mode 100644 index 000000000..e8c438e0f --- /dev/null +++ b/java/metalava/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 463936 + +file:platform/tools/metalava:/OWNERS diff --git a/java/metalava/main-config.xml b/java/metalava/main-config.xml new file mode 100644 index 000000000..c61196fc6 --- /dev/null +++ b/java/metalava/main-config.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<config xmlns="http://www.google.com/tools/metalava/config" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/> diff --git a/java/metalava/source-model-selection-config.xml b/java/metalava/source-model-selection-config.xml new file mode 100644 index 000000000..c61196fc6 --- /dev/null +++ b/java/metalava/source-model-selection-config.xml @@ -0,0 +1,19 @@ +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<config xmlns="http://www.google.com/tools/metalava/config" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.google.com/tools/metalava/config ../../../../tools/metalava/metalava/src/main/resources/schemas/config.xsd"/> diff --git a/java/ravenwood.go b/java/ravenwood.go index 908619d5f..a52f4053f 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -33,6 +33,8 @@ func RegisterRavenwoodBuildComponents(ctx android.RegistrationContext) { var ravenwoodLibContentTag = dependencyTag{name: "ravenwoodlibcontent"} var ravenwoodUtilsTag = dependencyTag{name: "ravenwoodutils"} var ravenwoodRuntimeTag = dependencyTag{name: "ravenwoodruntime"} +var ravenwoodDataTag = dependencyTag{name: "ravenwooddata"} +var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"} const ravenwoodUtilsName = "ravenwood-utils" const ravenwoodRuntimeName = "ravenwood-runtime" @@ -53,6 +55,13 @@ func getLibPath(archType android.ArchType) string { type ravenwoodTestProperties struct { Jni_libs []string + + // Specify another android_app module here to copy it to the test directory, so that + // the ravenwood test can access it. + // TODO: For now, we simply refer to another android_app module and copy it to the + // test directory. Eventually, android_ravenwood_test should support all the resource + // related properties and build resources from the `res/` directory. + Resource_apk *string } type ravenwoodTest struct { @@ -114,6 +123,11 @@ func (r *ravenwoodTest) DepsMutator(ctx android.BottomUpMutatorContext) { for _, lib := range r.ravenwoodTestProperties.Jni_libs { ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib) } + + // Resources APK + if resourceApk := proptools.String(r.ravenwoodTestProperties.Resource_apk); resourceApk != "" { + ctx.AddVariationDependencies(nil, ravenwoodTestResourceApkTag, resourceApk) + } } func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -175,6 +189,14 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installDeps = append(installDeps, installJni) } + resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks") + if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 { + for _, installFile := range resApk[0].FilesToInstall() { + installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile) + installDeps = append(installDeps, installResApk) + } + } + // Install our JAR with all dependencies ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...) } @@ -198,6 +220,9 @@ type ravenwoodLibgroupProperties struct { Libs []string Jni_libs []string + + // We use this to copy framework-res.apk to the ravenwood runtime directory. + Data []string } type ravenwoodLibgroup struct { @@ -236,6 +261,9 @@ func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) { for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs { ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib) } + for _, data := range r.ravenwoodLibgroupProperties.Data { + ctx.AddVariationDependencies(nil, ravenwoodDataTag, data) + } } func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -257,6 +285,14 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex installPath := android.PathForModuleInstall(ctx, r.BaseModuleName()) for _, lib := range r.ravenwoodLibgroupProperties.Libs { libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag) + if libModule == nil { + if ctx.Config().AllowMissingDependencies() { + ctx.AddMissingDependencies([]string{lib}) + } else { + ctx.PropertyErrorf("lib", "missing dependency %q", lib) + } + continue + } libJar := android.OutputFileForModule(ctx, libModule, "") ctx.InstallFile(installPath, lib+".jar", libJar) } @@ -266,6 +302,13 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path) } + dataInstallPath := installPath.Join(ctx, "ravenwood-data") + for _, data := range r.ravenwoodLibgroupProperties.Data { + libModule := ctx.GetDirectDepWithTag(data, ravenwoodDataTag) + file := android.OutputFileForModule(ctx, libModule, "") + ctx.InstallFile(dataInstallPath, file.Base(), file) + } + // Normal build should perform install steps ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install")) } diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go index 59612645c..d26db930d 100644 --- a/java/ravenwood_test.go +++ b/java/ravenwood_test.go @@ -57,6 +57,14 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers( name: "framework-rules.ravenwood", srcs: ["Rules.java"], } + android_app { + name: "app1", + sdk_version: "current", + } + android_app { + name: "app2", + sdk_version: "current", + } android_ravenwood_libgroup { name: "ravenwood-runtime", libs: [ @@ -67,6 +75,9 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers( "ravenwood-runtime-jni1", "ravenwood-runtime-jni2", ], + data: [ + "app1", + ], } android_ravenwood_libgroup { name: "ravenwood-utils", @@ -102,6 +113,7 @@ func TestRavenwoodRuntime(t *testing.T) { runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni1.so") runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/libred.so") runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so") + runtime.Output(installPathPrefix + "/ravenwood-runtime/ravenwood-data/app1.apk") utils := ctx.ModuleForTests("ravenwood-utils", "android_common") utils.Output(installPathPrefix + "/ravenwood-utils/framework-rules.ravenwood.jar") } @@ -143,6 +155,7 @@ func TestRavenwoodTest(t *testing.T) { "jni-lib2", "ravenwood-runtime-jni2", ], + resource_apk: "app2", sdk_version: "test_current", } `) @@ -169,6 +182,7 @@ func TestRavenwoodTest(t *testing.T) { module.Output(installPathPrefix + "/ravenwood-test/lib64/jni-lib1.so") module.Output(installPathPrefix + "/ravenwood-test/lib64/libblue.so") module.Output(installPathPrefix + "/ravenwood-test/lib64/libpink.so") + module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk") // ravenwood-runtime*.so are included in the runtime, so it shouldn't be emitted. for _, o := range module.AllOutputs() { diff --git a/java/sdk_library.go b/java/sdk_library.go index 1eb7ab834..a8cc1b81f 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -20,7 +20,6 @@ import ( "path" "path/filepath" "reflect" - "regexp" "sort" "strings" "sync" @@ -427,22 +426,10 @@ var ( apiScopeModuleLib, apiScopeSystemServer, } - apiLibraryAdditionalProperties = map[string]struct { - FullApiSurfaceStubLib string - AdditionalApiContribution string - }{ - "legacy.i18n.module.platform.api": { - FullApiSurfaceStubLib: "legacy.core.platform.api.stubs", - AdditionalApiContribution: "i18n.module.public.api.stubs.source.api.contribution", - }, - "stable.i18n.module.platform.api": { - FullApiSurfaceStubLib: "stable.core.platform.api.stubs", - AdditionalApiContribution: "i18n.module.public.api.stubs.source.api.contribution", - }, - "conscrypt.module.platform.api": { - FullApiSurfaceStubLib: "stable.core.platform.api.stubs", - AdditionalApiContribution: "conscrypt.module.public.api.stubs.source.api.contribution", - }, + apiLibraryAdditionalProperties = map[string]string{ + "legacy.i18n.module.platform.api": "i18n.module.public.api.stubs.source.api.contribution", + "stable.i18n.module.platform.api": "i18n.module.public.api.stubs.source.api.contribution", + "conscrypt.module.platform.api": "conscrypt.module.public.api.stubs.source.api.contribution", } ) @@ -650,17 +637,14 @@ type sdkLibraryProperties struct { Legacy_errors_allowed *bool } - // Determines if the module contributes to any api surfaces. - // This property should be set to true only if the module is listed under - // frameworks-base-api.bootclasspath in frameworks/base/api/Android.bp. - // Otherwise, this property should be set to false. - // Defaults to false. - Contribute_to_android_api *bool - // a list of aconfig_declarations module names that the stubs generated in this module // depend on. Aconfig_declarations []string + // Determines if the module generates the stubs from the api signature files + // instead of the source Java files. Defaults to true. + Build_from_text_stub *bool + // TODO: determines whether to create HTML doc or not // Html_doc *bool } @@ -1061,28 +1045,6 @@ const ( annotationsComponentName = "annotations.zip" ) -// A regular expression to match tags that reference a specific stubs component. -// -// It will only match if given a valid scope and a valid component. It is verfy strict -// to ensure it does not accidentally match a similar looking tag that should be processed -// by the embedded Library. -var tagSplitter = func() *regexp.Regexp { - // Given a list of literal string items returns a regular expression that will - // match any one of the items. - choice := func(items ...string) string { - return `\Q` + strings.Join(items, `\E|\Q`) + `\E` - } - - // Regular expression to match one of the scopes. - scopesRegexp := choice(allScopeNames...) - - // Regular expression to match one of the components. - componentsRegexp := choice(stubsSourceComponentName, apiTxtComponentName, removedApiTxtComponentName, annotationsComponentName) - - // Regular expression to match any combination of one scope and one component. - return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp)) -}() - func (module *commonToSdkLibraryAndImport) setOutputFiles(ctx android.ModuleContext) { if module.doctagPaths != nil { ctx.SetOutputFiles(module.doctagPaths, ".doctags") @@ -1516,6 +1478,13 @@ func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContex // Add other dependencies as normal. func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { + // If the module does not create an implementation library or defaults to stubs, + // mark the top level sdk library as stubs module as the module will provide stubs via + // "magic" when listed as a dependency in the Android.bp files. + notCreateImplLib := proptools.Bool(module.sdkLibraryProperties.Api_only) + preferStubs := proptools.Bool(module.sdkLibraryProperties.Default_to_stubs) + module.properties.Is_stubs_module = proptools.BoolPtr(notCreateImplLib || preferStubs) + var missingApiModules []string for _, apiScope := range module.getGeneratedApiScopes(ctx) { if apiScope.unstable { @@ -1740,30 +1709,13 @@ func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope) } -func (module *SdkLibrary) contributesToApiSurface(c android.Config) bool { - _, exists := c.GetApiLibraries()[module.Name()] - return exists -} - -// The listed modules are the special java_sdk_libraries where apiScope.kind do not match the -// api surface that the module contribute to. For example, the public droidstubs and java_library -// do not contribute to the public api surface, but contributes to the core platform api surface. -// This method returns the full api surface stub lib that -// the generated java_api_library should depend on. -func (module *SdkLibrary) alternativeFullApiSurfaceStubLib() string { - if val, ok := apiLibraryAdditionalProperties[module.Name()]; ok { - return val.FullApiSurfaceStubLib - } - return "" -} - // The listed modules' stubs contents do not match the corresponding txt files, // but require additional api contributions to generate the full stubs. // This method returns the name of the additional api contribution module // for corresponding sdk_library modules. func (module *SdkLibrary) apiLibraryAdditionalApiContribution() string { if val, ok := apiLibraryAdditionalProperties[module.Name()]; ok { - return val.AdditionalApiContribution + return val } return "" } @@ -2058,17 +2010,18 @@ func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookC mctx.CreateModule(DroidstubsFactory, &props, module.sdkComponentPropertiesForChildLibrary()).(*Droidstubs).CallHookIfAvailable(mctx) } -func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope, alternativeFullApiSurfaceStub string) { +func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) { props := struct { - Name *string - Visibility []string - Api_contributions []string - Libs []string - Static_libs []string - Full_api_surface_stub *string - System_modules *string - Enable_validation *bool - Stubs_type *string + Name *string + Visibility []string + Api_contributions []string + Libs []string + Static_libs []string + System_modules *string + Enable_validation *bool + Stubs_type *string + Sdk_version *string + Previous_api *string }{} props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope)) @@ -2092,34 +2045,29 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext, } props.Api_contributions = apiContributions - props.Libs = module.properties.Libs + + // Ensure that stub-annotations is added to the classpath before any other libs + props.Libs = []string{"stub-annotations"} + props.Libs = append(props.Libs, module.properties.Libs...) + props.Libs = append(props.Libs, module.properties.Static_libs...) props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...) props.Libs = append(props.Libs, module.scopeToProperties[apiScope].Libs...) - props.Libs = append(props.Libs, "stub-annotations") props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs - props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName()) - if alternativeFullApiSurfaceStub != "" { - props.Full_api_surface_stub = proptools.StringPtr(alternativeFullApiSurfaceStub) - } - - // android_module_lib_stubs_current.from-text only comprises api contributions from art, conscrypt and i18n. - // Thus, replace with android_module_lib_stubs_current_full.from-text, which comprises every api domains. - if apiScope.kind == android.SdkModule { - props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text") - } - - // java_sdk_library modules that set sdk_version as none does not depend on other api - // domains. Therefore, java_api_library created from such modules should not depend on - // full_api_surface_stubs but create and compile stubs by the java_api_library module - // itself. - if module.SdkVersion(mctx).Kind == android.SdkNone { - props.Full_api_surface_stub = nil - } props.System_modules = module.deviceProperties.System_modules props.Enable_validation = proptools.BoolPtr(true) props.Stubs_type = proptools.StringPtr("everything") + if module.deviceProperties.Sdk_version != nil { + props.Sdk_version = module.deviceProperties.Sdk_version + } + + if module.compareAgainstLatestApi(apiScope) { + // check against the latest released API + latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope)) + props.Previous_api = latestApiFilegroupName + } + mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary()) } @@ -2150,7 +2098,7 @@ func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHook } func (module *SdkLibrary) createTopLevelStubsLibrary( - mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) { + mctx android.DefaultableHookContext, apiScope *apiScope) { // Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false doDist := !mctx.Config().ReleaseHiddenApiExportableStubs() @@ -2159,7 +2107,7 @@ func (module *SdkLibrary) createTopLevelStubsLibrary( // Add the stub compiling java_library/java_api_library as static lib based on build config staticLib := module.sourceStubsLibraryModuleName(apiScope) - if mctx.Config().BuildFromTextStub() && contributesToApiSurface { + if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() { staticLib = module.apiLibraryModuleName(apiScope) } props.Static_libs = append(props.Static_libs, staticLib) @@ -2202,8 +2150,8 @@ func (module *SdkLibrary) UniqueApexVariations() bool { return module.uniqueApexVariations() } -func (module *SdkLibrary) ContributeToApi() bool { - return proptools.BoolDefault(module.sdkLibraryProperties.Contribute_to_android_api, false) +func (module *SdkLibrary) ModuleBuildFromTextStubs() bool { + return proptools.BoolDefault(module.sdkLibraryProperties.Build_from_text_stub, true) } // Creates the xml file that publicizes the runtime library @@ -2379,16 +2327,10 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont module.createStubsLibrary(mctx, scope) module.createExportableStubsLibrary(mctx, scope) - alternativeFullApiSurfaceStubLib := "" - if scope == apiScopePublic { - alternativeFullApiSurfaceStubLib = module.alternativeFullApiSurfaceStubLib() + if mctx.Config().BuildFromTextStub() && module.ModuleBuildFromTextStubs() { + module.createApiLibrary(mctx, scope) } - contributesToApiSurface := module.contributesToApiSurface(mctx.Config()) || alternativeFullApiSurfaceStubLib != "" - if contributesToApiSurface { - module.createApiLibrary(mctx, scope, alternativeFullApiSurfaceStubLib) - } - - module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface) + module.createTopLevelStubsLibrary(mctx, scope) module.createTopLevelExportableStubsLibrary(mctx, scope) } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index a8a1494ee..911e8b1e4 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -35,9 +35,6 @@ func TestJavaSdkLibrary(t *testing.T) { "29": {"foo"}, "30": {"bar", "barney", "baz", "betty", "foo", "fred", "quuz", "wilma"}, }), - android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) - }), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.BuildFlags = map[string]string{ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", @@ -923,6 +920,7 @@ func TestJavaSdkLibraryImport(t *testing.T) { } CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_sdklib.stubs`, `prebuilt_sdklib.stubs.source.test`, @@ -1588,9 +1586,6 @@ func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), - android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) - }), ).RunTestWithBp(t, ` java_sdk_library { name: "foo", @@ -1609,36 +1604,30 @@ func TestJavaSdkLibrary_ApiLibrary(t *testing.T) { `) testCases := []struct { - scope *apiScope - apiContributions []string - fullApiSurfaceStub string + scope *apiScope + apiContributions []string }{ { - scope: apiScopePublic, - apiContributions: []string{"foo.stubs.source.api.contribution"}, - fullApiSurfaceStub: "android_stubs_current", + scope: apiScopePublic, + apiContributions: []string{"foo.stubs.source.api.contribution"}, }, { - scope: apiScopeSystem, - apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, - fullApiSurfaceStub: "android_system_stubs_current", + scope: apiScopeSystem, + apiContributions: []string{"foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, }, { - scope: apiScopeTest, - apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, - fullApiSurfaceStub: "android_test_stubs_current", + scope: apiScopeTest, + apiContributions: []string{"foo.stubs.source.test.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, }, { - scope: apiScopeModuleLib, - apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, - fullApiSurfaceStub: "android_module_lib_stubs_current_full.from-text", + scope: apiScopeModuleLib, + apiContributions: []string{"foo.stubs.source.module_lib.api.contribution", "foo.stubs.source.system.api.contribution", "foo.stubs.source.api.contribution"}, }, } for _, c := range testCases { m := result.ModuleForTests(c.scope.apiLibraryModuleName("foo"), "android_common").Module().(*ApiLibrary) android.AssertArrayString(t, "Module expected to contain api contributions", c.apiContributions, m.properties.Api_contributions) - android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.fullApiSurfaceStub, *m.properties.Full_api_surface_stub) } } @@ -1708,9 +1697,6 @@ func TestSdkLibraryExportableStubsLibrary(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("foo"), - android.FixtureModifyConfig(func(config android.Config) { - config.SetApiLibraries([]string{"foo"}) - }), ).RunTestWithBp(t, ` aconfig_declarations { name: "bar", diff --git a/java/testing.go b/java/testing.go index 5ae326d93..a99baf8a2 100644 --- a/java/testing.go +++ b/java/testing.go @@ -52,6 +52,8 @@ var PrepareForTestWithJavaBuildComponents = android.GroupFixturePreparers( android.MockFS{ // Needed for linter used by java_library. "build/soong/java/lint_defaults.txt": nil, + // Needed for java components that invoke Metalava. + "build/soong/java/metalava/Android.bp": []byte(`filegroup {name: "metalava-config-files"}`), // Needed for apps that do not provide their own. "build/make/target/product/security": nil, // Required to generate Java used-by API coverage @@ -484,21 +486,17 @@ func gatherRequiredDepsForTest() string { } 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, - "android-non-updatable.stubs.test_module_lib": moduleLibDroidstubs, + "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.test_module_lib": moduleLibDroidstubs, } for _, droidstubs := range droidstubsStructs { @@ -527,6 +525,8 @@ func gatherRequiredDepsForTest() string { name: "%s", api_contributions: ["%s"], stubs_type: "everything", + sdk_version: "none", + system_modules: "none", } `, libName, droidstubs.name+".api.contribution") } |