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

Commit dcc42b6f authored by Jiakai Zhang's avatar Jiakai Zhang Committed by Gerrit Code Review
Browse files

Merge changes I7876b077,Ib2e7d5e6,I7d2d2e02,Ibf5322f8

* changes:
  Generate prebuilt_systemserverclasspath_fragment.
  Add a new SDK member type java_systemserver_libs.
  Add exported_systemserverclasspath_fragments to prebuilt_apex rule.
  Add prebuilt_systemserverclasspath_fragment rule.
parents 4352a8e6 a8d8660a
Loading
Loading
Loading
Loading
+37 −20
Original line number Diff line number Diff line
@@ -103,6 +103,10 @@ type PrebuiltCommonProperties struct {
	// List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX
	// bundle will create an APEX variant.
	Exported_bootclasspath_fragments []string

	// List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this
	// APEX bundle will create an APEX variant.
	Exported_systemserverclasspath_fragments []string
}

// initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the
@@ -174,7 +178,8 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
		tag := ctx.OtherModuleDependencyTag(child)

		name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
		if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
		if java.IsBootclasspathFragmentContentDepTag(tag) ||
			java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
			// If the exported java module provides a dex jar path then add it to the list of apexFiles.
			path := child.(interface {
				DexJarBuildPath() java.OptionalDexJarPath
@@ -194,8 +199,9 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
				}
				p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
			}
		} else if tag == exportedBootclasspathFragmentTag {
			// Visit the children of the bootclasspath_fragment.
		} else if tag == exportedBootclasspathFragmentTag ||
			tag == exportedSystemserverclasspathFragmentTag {
			// Visit the children of the bootclasspath_fragment and systemserver_fragment.
			return true
		}

@@ -311,21 +317,31 @@ func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) {
	}
}

func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag {
	dependencies := make(map[string]exportedDependencyTag)

	for _, dep := range p.prebuiltCommonProperties.Exported_java_libs {
		dependencies[dep] = exportedJavaLibTag
	}

	for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
		dependencies[dep] = exportedBootclasspathFragmentTag
	}

	for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments {
		dependencies[dep] = exportedSystemserverclasspathFragmentTag
	}

	return dependencies
}

// prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents.
func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) {
	module := ctx.Module()
	// Add dependencies onto the java modules that represent the java libraries that are provided by
	// and exported from this prebuilt apex.
	for _, exported := range p.prebuiltCommonProperties.Exported_java_libs {
		dep := android.PrebuiltNameFromSource(exported)
		ctx.AddDependency(module, exportedJavaLibTag, dep)
	}

	// Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt
	// apex.
	for _, exported := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
		dep := android.PrebuiltNameFromSource(exported)
		ctx.AddDependency(module, exportedBootclasspathFragmentTag, dep)
	for dep, tag := range p.getExportedDependencies() {
		prebuiltDep := android.PrebuiltNameFromSource(dep)
		ctx.AddDependency(module, tag, prebuiltDep)
	}
}

@@ -576,9 +592,9 @@ func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, ap
// A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
// the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
// the listed modules need access to files from within the prebuilt .apex file.
func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string, properties *PrebuiltCommonProperties) {
func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
	// Only create the deapexer module if it is needed.
	if len(properties.Exported_java_libs)+len(properties.Exported_bootclasspath_fragments) == 0 {
	if len(p.getExportedDependencies()) == 0 {
		return
	}

@@ -676,6 +692,7 @@ var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{}
var (
	exportedJavaLibTag                       = exportedDependencyTag{name: "exported_java_libs"}
	exportedBootclasspathFragmentTag         = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
	exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
)

var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
@@ -716,7 +733,7 @@ func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext)
	createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)

	apexFileSource := ":" + apexSelectorModuleName
	createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, p.prebuiltCommonProperties)
	p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)

	// Add a source reference to retrieve the selected apex from the selector module.
	p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -919,7 +936,7 @@ func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
	createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)

	apexFileSource := ":" + apexExtractorModuleName
	createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, a.prebuiltCommonProperties)
	a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)

	// After passing the arch specific src properties to the creating the apex selector module
	a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
+50 −0
Original line number Diff line number Diff line
@@ -181,3 +181,53 @@ func TestSystemServerClasspathFragmentWithContentNotInMake(t *testing.T) {
			}
		`)
}

func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithSystemserverclasspathFragment,
		prepareForTestWithMyapex,
		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
	).RunTestWithBp(t, `
		prebuilt_apex {
			name: "myapex",
			arch: {
				arm64: {
					src: "myapex-arm64.apex",
				},
				arm: {
					src: "myapex-arm.apex",
				},
			},
			exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
		}

		java_import {
			name: "foo",
			jars: ["foo.jar"],
			apex_available: [
				"myapex",
			],
		}

		prebuilt_systemserverclasspath_fragment {
			name: "mysystemserverclasspathfragment",
			prefer: true,
			contents: [
				"foo",
			],
			apex_available: [
				"myapex",
			],
		}
	`)

	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
		`myapex.apex.selector`,
		`prebuilt_mysystemserverclasspathfragment`,
	})

	java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
		`myapex.deapexer`,
		`prebuilt_foo`,
	})
}
+32 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ func RegisterJavaSdkMemberTypes() {
	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
	android.RegisterSdkMemberType(javaLibsSdkMemberType)
	android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
	android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType)
	android.RegisterSdkMemberType(javaTestSdkMemberType)
}

@@ -146,6 +147,37 @@ var (
		onlyCopyJarToSnapshot,
	}

	// Supports adding java systemserver libraries to module_exports and sdk.
	//
	// The build has some implicit dependencies (via the systemserver jars configuration) on a number
	// of modules that are part of the java systemserver classpath and which are provided by mainline
	// modules but which are not otherwise used outside those mainline modules.
	//
	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
	// either java_libs, or java_header_libs would end up exporting more information than was strictly
	// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
	// the sdk/module_exports without exposing any unnecessary information.
	javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
		android.SdkMemberTypeBase{
			PropertyName: "java_systemserver_libs",
			SupportsSdk:  true,
		},
		func(ctx android.SdkMemberContext, j *Library) android.Path {
			// Java systemserver libs are only provided in the SDK to provide access to their dex
			// implementation jar for use by dexpreopting. They do not need to provide an actual
			// implementation jar but the java_import will need a file that exists so just copy an empty
			// file. Any attempt to use that file as a jar will cause a build error.
			return ctx.SnapshotBuilder().EmptyFile()
		},
		func(osPrefix, name string) string {
			// Create a special name for the implementation jar to try and provide some useful information
			// to a developer that attempts to compile against this.
			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
			return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
		},
		onlyCopyJarToSnapshot,
	}

	// Supports adding java test libraries to module_exports but not sdk.
	javaTestSdkMemberType = &testSdkMemberType{
		SdkMemberTypeBase: android.SdkMemberTypeBase{
+115 −1
Original line number Diff line number Diff line
@@ -23,11 +23,19 @@ import (

func init() {
	registerSystemserverClasspathBuildComponents(android.InitRegistrationContext)

	android.RegisterSdkMemberType(&systemServerClasspathFragmentMemberType{
		SdkMemberTypeBase: android.SdkMemberTypeBase{
			PropertyName: "systemserverclasspath_fragments",
			SupportsSdk:  true,
		},
	})
}

func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("platform_systemserverclasspath", platformSystemServerClasspathFactory)
	ctx.RegisterModuleType("systemserverclasspath_fragment", systemServerClasspathFactory)
	ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory)
}

type platformSystemServerClasspathModule struct {
@@ -61,6 +69,7 @@ func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleC
type SystemServerClasspathModule struct {
	android.ModuleBase
	android.ApexModuleBase
	android.SdkBase

	ClasspathFragmentBase

@@ -85,6 +94,7 @@ func systemServerClasspathFactory() android.Module {
	m := &SystemServerClasspathModule{}
	m.AddProperties(&m.properties)
	android.InitApexModule(m)
	android.InitSdkAwareModule(m)
	initClasspathFragment(m, SYSTEMSERVERCLASSPATH)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
@@ -112,7 +122,7 @@ func (s *SystemServerClasspathModule) configuredJars(ctx android.ModuleContext)
	_, unknown = android.RemoveFromList("geotz", unknown)

	// For non test apexes, make sure that all contents are actually declared in make.
	if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 {
	if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
		ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS", unknown)
	}

@@ -128,12 +138,33 @@ func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebui
	return false
}

// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
// they were specified using java_systemserver_libs or java_sdk_libs.
func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
	// If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
	// property, otherwise treat if it was specified in the java_systemserver_libs property.
	if javaSdkLibrarySdkMemberType.IsInstance(child) {
		return javaSdkLibrarySdkMemberType
	}

	return javaSystemserverLibsSdkMemberType
}

func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool {
	return true
}

// Contents of system server fragments in an apex are considered to be directly in the apex, as if
// they were listed in java_libs.
func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}

// Contents of system server fragments require files from prebuilt apex files.
func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {}

var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag
var _ android.SdkMemberDependencyTag = systemServerClasspathFragmentContentDepTag
var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag
var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag

// The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{}
@@ -144,8 +175,14 @@ func IsSystemServerClasspathFragmentContentDepTag(tag blueprint.DependencyTag) b

func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
	module := ctx.Module()
	_, isSourceModule := module.(*SystemServerClasspathModule)

	for _, name := range s.properties.Contents {
		// A systemserverclasspath_fragment must depend only on other source modules, while the
		// prebuilt_systemserverclasspath_fragment_fragment must only depend on other prebuilt modules.
		if !isSourceModule {
			name = android.PrebuiltNameFromSource(name)
		}
		ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name)
	}
}
@@ -155,3 +192,80 @@ func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) {
	dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
	dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...)
}

type systemServerClasspathFragmentMemberType struct {
	android.SdkMemberTypeBase
}

func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
	ctx.AddVariationDependencies(nil, dependencyTag, names...)
}

func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool {
	_, ok := module.(*SystemServerClasspathModule)
	return ok
}

func (s *systemServerClasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_systemserverclasspath_fragment")
}

func (s *systemServerClasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
	return &systemServerClasspathFragmentSdkMemberProperties{}
}

type systemServerClasspathFragmentSdkMemberProperties struct {
	android.SdkMemberPropertiesBase

	// Contents of the systemserverclasspath fragment
	Contents []string
}

func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
	module := variant.(*SystemServerClasspathModule)

	s.Contents = module.properties.Contents
}

func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
	builder := ctx.SnapshotBuilder()
	requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true)

	if len(s.Contents) > 0 {
		propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency)
	}
}

var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil)

// A prebuilt version of the systemserverclasspath_fragment module.
type prebuiltSystemServerClasspathModule struct {
	SystemServerClasspathModule
	prebuilt android.Prebuilt
}

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

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

func (module *prebuiltSystemServerClasspathModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
	return nil
}

var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltSystemServerClasspathModule)(nil)

func prebuiltSystemServerClasspathModuleFactory() android.Module {
	m := &prebuiltSystemServerClasspathModule{}
	m.AddProperties(&m.properties)
	// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
	// array.
	android.InitPrebuiltModule(m, &[]string{"placeholder"})
	android.InitApexModule(m)
	android.InitSdkAwareModule(m)
	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
	return m
}
+2 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ bootstrap_go_package {
        "soong-android",
        "soong-apex",
        "soong-cc",
        "soong-dexpreopt",
        "soong-java",
    ],
    srcs: [
@@ -31,6 +32,7 @@ bootstrap_go_package {
        "license_sdk_test.go",
        "member_trait_test.go",
        "sdk_test.go",
        "systemserverclasspath_fragment_sdk_test.go",
        "testing.go",
    ],
    pluginFor: ["soong_build"],
Loading