Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3754ba0 authored by Anton Hansson's avatar Anton Hansson Committed by Android (Google) Code Review
Browse files

Merge "Let APEX build against preferred java_sdk_library_import" into rvc-dev

parents f4a5492e f642a31a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1964,7 +1964,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				}
			case javaLibTag:
				switch child.(type) {
				case *java.Library, *java.SdkLibrary, *java.DexImport:
				case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport:
					af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
					if !af.Ok() {
						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
+127 −2
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer)
func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
	t.Helper()
	ctx, config := testApexContext(t, bp, handlers...)
	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
	_, errs := ctx.ParseBlueprintsFiles(".")
	android.FailIfErrored(t, errs)
	_, errs = ctx.PrepareBuildActions(config)
	android.FailIfErrored(t, errs)
@@ -196,6 +196,11 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
	}

	ctx := android.NewTestArchContext()

	// from android package
	android.RegisterPackageBuildComponents(ctx)
	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)

	ctx.RegisterModuleType("apex", BundleFactory)
	ctx.RegisterModuleType("apex_test", testApexBundleFactory)
	ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
@@ -209,6 +214,12 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)

	cc.RegisterRequiredBuildComponentsForTest(ctx)

	// Register this after the prebuilt mutators have been registered (in
	// cc.RegisterRequiredBuildComponentsForTest) to match what happens at runtime.
	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)

	ctx.RegisterModuleType("cc_test", cc.TestFactory)
	ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
	ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
@@ -219,7 +230,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
	java.RegisterJavaBuildComponents(ctx)
	java.RegisterSystemModulesBuildComponents(ctx)
	java.RegisterAppBuildComponents(ctx)
	ctx.RegisterModuleType("java_sdk_library", java.SdkLibraryFactory)
	java.RegisterSdkLibraryBuildComponents(ctx)

	ctx.PreDepsMutators(RegisterPreDepsMutators)
	ctx.PostDepsMutators(RegisterPostDepsMutators)
@@ -4067,6 +4078,9 @@ var filesForSdkLibrary = map[string][]byte{
	"api/system-removed.txt": nil,
	"api/test-current.txt":   nil,
	"api/test-removed.txt":   nil,

	// For java_sdk_library_import
	"a.jar": nil,
}

func TestJavaSDKLibrary(t *testing.T) {
@@ -4193,6 +4207,117 @@ func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
	}
}

func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
	ctx, _ := testApex(t, ``,
		withFiles(map[string][]byte{
			"apex/a.java":             nil,
			"apex/apex_manifest.json": nil,
			"apex/Android.bp": []byte(`
		package {
			default_visibility: ["//visibility:private"],
		}

		apex {
			name: "myapex",
			key: "myapex.key",
			java_libs: ["foo", "bar"],
		}

		apex_key {
			name: "myapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		java_library {
			name: "bar",
			srcs: ["a.java"],
			libs: ["foo"],
			apex_available: ["myapex"],
			sdk_version: "none",
			system_modules: "none",
		}
`),
			"source/a.java":          nil,
			"source/api/current.txt": nil,
			"source/api/removed.txt": nil,
			"source/Android.bp": []byte(`
		package {
			default_visibility: ["//visibility:private"],
		}

		java_sdk_library {
			name: "foo",
			visibility: ["//apex"],
			srcs: ["a.java"],
			api_packages: ["foo"],
			apex_available: ["myapex"],
			sdk_version: "none",
			system_modules: "none",
			public: {
				enabled: true,
			},
		}
`),
			"prebuilt/a.jar": nil,
			"prebuilt/Android.bp": []byte(`
		package {
			default_visibility: ["//visibility:private"],
		}

		java_sdk_library_import {
			name: "foo",
			visibility: ["//apex", "//source"],
			apex_available: ["myapex"],
			prefer: true,
			public: {
				jars: ["a.jar"],
			},
		}
`),
		}),
	)

	// java_sdk_library installs both impl jar and permission XML
	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"javalib/bar.jar",
		"javalib/foo.jar",
		"etc/permissions/foo.xml",
	})

	// The bar library should depend on the implementation jar.
	barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
	if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
		t.Errorf("expected %q, found %#q", expected, actual)
	}
}

func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
	testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
		apex {
			name: "myapex",
			key: "myapex.key",
			java_libs: ["foo"],
		}

		apex_key {
			name: "myapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		java_sdk_library_import {
			name: "foo",
			apex_available: ["myapex"],
			prefer: true,
			public: {
				jars: ["a.jar"],
			},
		}

	`, withFiles(filesForSdkLibrary))
}

func TestCompatConfig(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
+120 −35
Original line number Diff line number Diff line
@@ -632,6 +632,16 @@ func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android
	return true
}

// Module name of the runtime implementation library
func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
	return c.moduleBase.BaseModuleName() + ".impl"
}

// Module name of the XML file for the lib
func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
	return c.moduleBase.BaseModuleName() + sdkXmlFileSuffix
}

// Name of the java_library module that compiles the stubs source.
func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
	return c.namingScheme.stubsLibraryModuleName(apiScope, c.moduleBase.BaseModuleName())
@@ -861,7 +871,7 @@ type SdkLibraryComponentDependency interface {
var _ SdkLibraryComponentDependency = (*Library)(nil)
var _ SdkLibraryComponentDependency = (*Import)(nil)
var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
var _ SdkLibraryComponentDependency = (*sdkLibraryImport)(nil)
var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil)

// Provides access to sdk_version related header and implentation jars.
type SdkLibraryDependency interface {
@@ -947,16 +957,24 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext)
	return generatedScopes
}

var xmlPermissionsFileTag = dependencyTag{name: "xml-permissions-file"}
type sdkLibraryComponentTag struct {
	blueprint.BaseDependencyTag
	name string
}

// Mark this tag so dependencies that use it are excluded from visibility enforcement.
func (t sdkLibraryComponentTag) ExcludeFromVisibilityEnforcement() {}

var xmlPermissionsFileTag = sdkLibraryComponentTag{name: "xml-permissions-file"}

func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
	if dt, ok := depTag.(dependencyTag); ok {
	if dt, ok := depTag.(sdkLibraryComponentTag); ok {
		return dt == xmlPermissionsFileTag
	}
	return false
}

var implLibraryTag = dependencyTag{name: "impl-library"}
var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}

func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
	for _, apiScope := range module.getGeneratedApiScopes(ctx) {
@@ -981,7 +999,7 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {

		if module.sharedLibrary() {
			// Add dependency to the rule for generating the xml permissions file
			ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
			ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName())
		}

		// Only add the deps for the library if it is actually going to be built.
@@ -1028,20 +1046,10 @@ func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
	}
	entriesList := module.Library.AndroidMkEntries()
	entries := &entriesList[0]
	entries.Required = append(entries.Required, module.xmlFileName())
	entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
	return entriesList
}

// Module name of the runtime implementation library
func (module *SdkLibrary) implLibraryModuleName() string {
	return module.BaseModuleName() + ".impl"
}

// Module name of the XML file for the lib
func (module *SdkLibrary) xmlFileName() string {
	return module.BaseModuleName() + sdkXmlFileSuffix
}

// The dist path of the stub artifacts
func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
	if module.ModuleBase.Owner() != "" {
@@ -1339,7 +1347,7 @@ func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
		Lib_name       *string
		Apex_available []string
	}{
		Name:           proptools.StringPtr(module.xmlFileName()),
		Name:           proptools.StringPtr(module.xmlPermissionsModuleName()),
		Lib_name:       proptools.StringPtr(module.BaseModuleName()),
		Apex_available: module.ApexProperties.Apex_available,
	}
@@ -1387,7 +1395,7 @@ func getApexNameForModule(module android.Module) string {
//
// If either this or the other module are on the platform then this will return
// false.
func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
func withinSameApexAs(module android.ApexModule, other android.Module) bool {
	name := module.ApexName()
	return name != "" && getApexNameForModule(other) == name
}
@@ -1408,7 +1416,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS
		// Only allow access to the implementation library in the following condition:
		// * No sdk_version specified on the referencing module.
		// * The referencing module is in the same apex as this.
		if sdkVersion.kind == sdkPrivate || module.withinSameApexAs(ctx.Module()) {
		if sdkVersion.kind == sdkPrivate || withinSameApexAs(module, ctx.Module()) {
			if headerJars {
				return module.HeaderJars()
			} else {
@@ -1712,7 +1720,7 @@ type sdkLibraryImportProperties struct {
	Libs []string
}

type sdkLibraryImport struct {
type SdkLibraryImport struct {
	android.ModuleBase
	android.DefaultableModuleBase
	prebuilt android.Prebuilt
@@ -1725,9 +1733,17 @@ type sdkLibraryImport struct {
	scopeProperties map[*apiScope]*sdkLibraryScopeProperties

	commonToSdkLibraryAndImport

	// The reference to the implementation library created by the source module.
	// Is nil if the source module does not exist.
	implLibraryModule *Library

	// The reference to the xml permissions module created by the source module.
	// Is nil if the source module does not exist.
	xmlPermissionsFileModule *sdkLibraryXml
}

var _ SdkLibraryDependency = (*sdkLibraryImport)(nil)
var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)

// The type of a structure that contains a field of type sdkLibraryScopeProperties
// for each apiscope in allApiScopes, e.g. something like:
@@ -1769,7 +1785,7 @@ func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProp

// java_sdk_library_import imports a prebuilt java_sdk_library.
func sdkLibraryImportFactory() android.Module {
	module := &sdkLibraryImport{}
	module := &SdkLibraryImport{}

	allScopeProperties, scopeToProperties := createPropertiesInstance()
	module.scopeProperties = scopeToProperties
@@ -1791,15 +1807,15 @@ func sdkLibraryImportFactory() android.Module {
	return module
}

func (module *sdkLibraryImport) Prebuilt() *android.Prebuilt {
func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt {
	return &module.prebuilt
}

func (module *sdkLibraryImport) Name() string {
func (module *SdkLibraryImport) Name() string {
	return module.prebuilt.Name(module.ModuleBase.Name())
}

func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {

	// If the build is configured to use prebuilts then force this to be preferred.
	if mctx.Config().UnbundledBuildUsePrebuiltSdks() {
@@ -1824,7 +1840,7 @@ func (module *sdkLibraryImport) createInternalModules(mctx android.DefaultableHo
	*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
}

func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
	// Creates a java import for the jar with ".stubs" suffix
	props := struct {
		Name        *string
@@ -1846,7 +1862,7 @@ func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
	mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}

func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
	props := struct {
		Name   *string
		Srcs   []string
@@ -1860,7 +1876,7 @@ func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.Defaulta
	props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
}

func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
	for apiScope, scopeProperties := range module.scopeProperties {
		if len(scopeProperties.Jars) == 0 {
			continue
@@ -1874,13 +1890,35 @@ func (module *sdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext)
			ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
		}
	}

	implName := module.implLibraryModuleName()
	if ctx.OtherModuleExists(implName) {
		ctx.AddVariationDependencies(nil, implLibraryTag, implName)

		xmlPermissionsModuleName := module.xmlPermissionsModuleName()
		if module.sharedLibrary() && ctx.OtherModuleExists(xmlPermissionsModuleName) {
			// Add dependency to the rule for generating the xml permissions file
			ctx.AddDependency(module, xmlPermissionsFileTag, xmlPermissionsModuleName)
		}
	}
}

func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
	depTag := mctx.OtherModuleDependencyTag(dep)
	if depTag == xmlPermissionsFileTag {
		return true
	}

	// None of the other dependencies of the java_sdk_library_import are in the same apex
	// as the one that references this module.
	return false
}

func (module *sdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
	return module.commonOutputFiles(tag)
}

func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// Record the paths to the prebuilt stubs library and stubs source.
	ctx.VisitDirectDeps(func(to android.Module) {
		tag := ctx.OtherModuleDependencyTag(to)
@@ -1893,6 +1931,18 @@ func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
			// Extract information from the dependency. The exact information extracted
			// is determined by the nature of the dependency which is determined by the tag.
			scopeTag.extractDepInfo(ctx, to, scopePaths)
		} else if tag == implLibraryTag {
			if implLibrary, ok := to.(*Library); ok {
				module.implLibraryModule = implLibrary
			} else {
				ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
			}
		} else if tag == xmlPermissionsFileTag {
			if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
				module.xmlPermissionsFileModule = xmlPermissionsFileModule
			} else {
				ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
			}
		}
	})

@@ -1908,20 +1958,55 @@ func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
	}
}

func (module *sdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {

	// For consistency with SdkLibrary make the implementation jar available to libraries that
	// are within the same APEX.
	implLibraryModule := module.implLibraryModule
	if implLibraryModule != nil && withinSameApexAs(module, ctx.Module()) {
		if headerJars {
			return implLibraryModule.HeaderJars()
		} else {
			return implLibraryModule.ImplementationJars()
		}
	}

	return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
}

// to satisfy SdkLibraryDependency interface
func (module *sdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
	// This module is just a wrapper for the prebuilt stubs.
	return module.sdkJars(ctx, sdkVersion)
	return module.sdkJars(ctx, sdkVersion, true)
}

// to satisfy SdkLibraryDependency interface
func (module *sdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths {
	// This module is just a wrapper for the stubs.
	return module.sdkJars(ctx, sdkVersion)
	return module.sdkJars(ctx, sdkVersion, false)
}

// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) DexJar() android.Path {
	if module.implLibraryModule == nil {
		return nil
	} else {
		return module.implLibraryModule.DexJar()
	}
}

// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
	if module.implLibraryModule == nil {
		return nil
	} else {
		return module.implLibraryModule.JacocoReportClassesFile()
	}
}

// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
	return module.BaseModuleName()
}

//