diff --git a/java/sdk_library.go b/java/sdk_library.go index e5ee39705..223be5cf7 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -534,6 +534,11 @@ type scopePaths struct { // This is not the implementation jar, it still only contains stubs. stubsImplPath android.Paths + // The dex jar for the stubs. + // + // This is not the implementation jar, it still only contains stubs. + stubsDexJarPath android.Path + // The API specification file, e.g. system_current.txt. currentApiFilePath android.OptionalPath @@ -549,6 +554,9 @@ func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.Modul lib := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) paths.stubsHeaderPath = lib.HeaderJars paths.stubsImplPath = lib.ImplementationJars + + libDep := dep.(UsesLibraryDependency) + paths.stubsDexJarPath = libDep.DexJarBuildPath() return nil } else { return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library") @@ -825,8 +833,22 @@ func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android. return PrebuiltJars(ctx, c.moduleBase.BaseModuleName(), sdkVersion) } + paths := c.selectScopePaths(ctx, sdkVersion.Kind) + if paths == nil { + return nil + } + + return paths.stubsHeaderPath +} + +// selectScopePaths returns the *scopePaths appropriate for the specific kind. +// +// If the module does not support the specific kind then it will return the *scopePaths for the +// closest kind which is a subset of the requested kind. e.g. if requesting android.SdkModule then +// it will return *scopePaths for android.SdkSystem if available or android.SdkPublic of not. +func (c *commonToSdkLibraryAndImport) selectScopePaths(ctx android.BaseModuleContext, kind android.SdkKind) *scopePaths { var apiScope *apiScope - switch sdkVersion.Kind { + switch kind { case android.SdkSystem: apiScope = apiScopeSystem case android.SdkModule: @@ -851,7 +873,17 @@ func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android. return nil } - return paths.stubsHeaderPath + return paths +} + +// to satisfy SdkLibraryDependency interface +func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path { + paths := c.selectScopePaths(ctx, kind) + if paths == nil { + return nil + } + + return paths.stubsDexJarPath } func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} { @@ -944,6 +976,10 @@ type SdkLibraryDependency interface { // jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise // they are identical to the corresponding header jars. SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths + + // SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing + // tool which processes dex files. + SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) android.Path } type SdkLibrary struct { @@ -1781,6 +1817,9 @@ type sdkLibraryImportProperties struct { // List of shared java libs, common to all scopes, that this module has // dependencies to Libs []string + + // If set to true, compile dex files for the stubs. Defaults to false. + Compile_dex *bool } type SdkLibraryImport struct { @@ -1916,6 +1955,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl Libs []string Jars []string Prefer *bool + Compile_dex *bool }{} props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope)) props.Sdk_version = scopeProperties.Sdk_version @@ -1927,6 +1967,9 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl // The imports are preferred if the java_sdk_library_import is preferred. props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer()) + // The imports need to be compiled to dex if the java_sdk_library_import requests it. + props.Compile_dex = module.properties.Compile_dex + mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary()) } @@ -2348,6 +2391,9 @@ type sdkLibrarySdkMemberProperties struct { // otherwise. Shared_library *bool + // True if the stub imports should produce dex jars. + Compile_dex *bool + // The paths to the doctag files to add to the prebuilt. Doctag_paths android.Paths } @@ -2389,6 +2435,7 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe s.Libs = sdk.properties.Libs s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) + s.Compile_dex = sdk.dexProperties.Compile_dex s.Doctag_paths = sdk.doctagPaths } @@ -2399,6 +2446,9 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo if s.Shared_library != nil { propertySet.AddProperty("shared_library", *s.Shared_library) } + if s.Compile_dex != nil { + propertySet.AddProperty("compile_dex", *s.Compile_dex) + } for _, apiScope := range allApiScopes { if properties, ok := s.Scopes[apiScope]; ok { diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 54916d8bb..601698121 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -1089,6 +1089,80 @@ sdk_snapshot { ) } +func TestSnapshotWithJavaSdkLibrary_CompileDex(t *testing.T) { + result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, ` + sdk { + name: "mysdk", + java_sdk_libs: ["myjavalib"], + } + + java_sdk_library { + name: "myjavalib", + srcs: ["Test.java"], + sdk_version: "current", + shared_library: false, + compile_dex: true, + public: { + enabled: true, + }, + system: { + enabled: true, + }, + } + `) + + CheckSnapshot(t, result, "mysdk", "", + checkUnversionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_sdk_library_import { + name: "myjavalib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + shared_library: false, + compile_dex: true, + public: { + jars: ["sdk_library/public/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], + current_api: "sdk_library/public/myjavalib.txt", + removed_api: "sdk_library/public/myjavalib-removed.txt", + sdk_version: "current", + }, + system: { + jars: ["sdk_library/system/myjavalib-stubs.jar"], + stub_srcs: ["sdk_library/system/myjavalib_stub_sources"], + current_api: "sdk_library/system/myjavalib.txt", + removed_api: "sdk_library/system/myjavalib-removed.txt", + sdk_version: "system_current", + }, +} +`), + snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) { + ctx := android.ModuleInstallPathContextForTesting(result.Config) + dexJarBuildPath := func(name string, kind android.SdkKind) string { + dep := result.Module(name, "android_common").(java.SdkLibraryDependency) + path := dep.SdkApiStubDexJar(ctx, kind) + return path.RelativeToTop().String() + } + + dexJarPath := dexJarBuildPath("myjavalib", android.SdkPublic) + android.AssertStringEquals(t, "source dex public stubs jar build path", "out/soong/.intermediates/myjavalib.stubs/android_common/dex/myjavalib.stubs.jar", dexJarPath) + + dexJarPath = dexJarBuildPath("myjavalib", android.SdkSystem) + systemDexJar := "out/soong/.intermediates/myjavalib.stubs.system/android_common/dex/myjavalib.stubs.system.jar" + android.AssertStringEquals(t, "source dex system stubs jar build path", systemDexJar, dexJarPath) + + // This should fall back to system as module is not available. + dexJarPath = dexJarBuildPath("myjavalib", android.SdkModule) + android.AssertStringEquals(t, "source dex module stubs jar build path", systemDexJar, dexJarPath) + + dexJarPath = dexJarBuildPath(android.PrebuiltNameFromSource("myjavalib"), android.SdkPublic) + android.AssertStringEquals(t, "prebuilt dex public stubs jar build path", "out/soong/.intermediates/snapshot/prebuilt_myjavalib.stubs/android_common/dex/myjavalib.stubs.jar", dexJarPath) + }), + ) +} + func TestSnapshotWithJavaSdkLibrary_SdkVersion_None(t *testing.T) { result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, ` sdk {