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

Commit dc2c1c26 authored by Jiakai Zhang's avatar Jiakai Zhang Committed by Automerger Merge Worker
Browse files

Merge "Revert^2 "Preopt APEX system server jars."" am: c9f9d56e

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1828115

Change-Id: I2a991341934af96455f136cbe44ef824f5e3e7f5
parents d19ed278 c9f9d56e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1659,6 +1659,20 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
	return ConfiguredJarList{apexes, jars}
}

// Append a list of (apex, jar) pairs to the list.
func (l *ConfiguredJarList) AppendList(other ConfiguredJarList) ConfiguredJarList {
	apexes := make([]string, 0, l.Len()+other.Len())
	jars := make([]string, 0, l.Len()+other.Len())

	apexes = append(apexes, l.apexes...)
	jars = append(jars, l.jars...)

	apexes = append(apexes, other.apexes...)
	jars = append(jars, other.jars...)

	return ConfiguredJarList{apexes, jars}
}

// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
	apexes := make([]string, 0, l.Len())
+5 −0
Original line number Diff line number Diff line
@@ -1522,6 +1522,11 @@ func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaMod
	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
	af.lintDepSets = module.LintDepSets()
	af.customStem = module.Stem() + ".jar"
	if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
		for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
		}
	}
	return af
}

+33 −21
Original line number Diff line number Diff line
@@ -110,17 +110,12 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo
		return true
	}

	// Don't preopt system server jars that are updatable.
	if global.ApexSystemServerJars.ContainsJar(module.Name) {
		return true
	}

	// If OnlyPreoptBootImageAndSystemServer=true and module is not in boot class path skip
	// Also preopt system server jars since selinux prevents system server from loading anything from
	// /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
	// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
	if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
		!global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk {
		!AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk {
		return true
	}

@@ -201,6 +196,14 @@ func bootProfileCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig,
	return profilePath
}

// Returns the dex location of a system server java library.
func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
	if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
		return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
	}
	return fmt.Sprintf("/system/framework/%s.jar", lib)
}

func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
	module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
	appImage bool, generateDM bool) {
@@ -216,6 +219,13 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
	}

	toOdexPath := func(path string) string {
		if global.ApexSystemServerJars.ContainsJar(module.Name) {
			return filepath.Join(
				"/system/framework/oat",
				arch.String(),
				strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
		}

		return filepath.Join(
			filepath.Dir(path),
			"oat",
@@ -234,20 +244,21 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g

	invocationPath := odexPath.ReplaceExtension(ctx, "invocation")

	systemServerJars := NonApexSystemServerJars(ctx, global)
	systemServerJars := AllSystemServerJars(ctx, global)

	rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
	rule.Command().FlagWithOutput("rm -f ", odexPath)

	if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
	if jarIndex := systemServerJars.IndexOfJar(module.Name); jarIndex >= 0 {
		// System server jars should be dexpreopted together: class loader context of each jar
		// should include all preceding jars on the system server classpath.

		var clcHost android.Paths
		var clcTarget []string
		for _, lib := range systemServerJars[:jarIndex] {
		for i := 0; i < jarIndex; i++ {
			lib := systemServerJars.Jar(i)
			clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
			clcTarget = append(clcTarget, filepath.Join("/system/framework", lib+".jar"))
			clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
		}

		// Copy the system server jar to a predefined location where dex2oat will find it.
@@ -362,7 +373,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g

	if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
		var compilerFilter string
		if global.SystemServerJars.ContainsJar(module.Name) {
		if systemServerJars.ContainsJar(module.Name) {
			// Jars of system server, use the product option if it is set, speed otherwise.
			if global.SystemServerCompilerFilter != "" {
				compilerFilter = global.SystemServerCompilerFilter
@@ -416,7 +427,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g

	// PRODUCT_SYSTEM_SERVER_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
	// PRODUCT_OTHER_JAVA_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
	if global.SystemServerJars.ContainsJar(module.Name) {
	if systemServerJars.ContainsJar(module.Name) {
		if global.AlwaysSystemServerDebugInfo {
			debugInfo = true
		} else if global.NeverSystemServerDebugInfo {
@@ -518,14 +529,15 @@ func makefileMatch(pattern, s string) bool {
	}
}

var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars")
var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")

// TODO: eliminate the superficial global config parameter by moving global config definition
// from java subpackage to dexpreopt.
func NonApexSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
	return ctx.Config().Once(nonApexSystemServerJarsKey, func() interface{} {
		return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.ApexSystemServerJars.CopyOfJars())
	}).([]string)
func AllSystemServerJars(ctx android.PathContext, global *GlobalConfig) *android.ConfiguredJarList {
	return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
		allSystemServerJars := global.SystemServerJars.AppendList(global.ApexSystemServerJars)
		return &allSystemServerJars
	}).(*android.ConfiguredJarList)
}

// A predefined location for the system server dex jars. This is needed in order to generate
@@ -551,12 +563,12 @@ func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
	mctx, isModule := ctx.(android.ModuleContext)
	if isModule {
		config := GetGlobalConfig(ctx)
		jars := NonApexSystemServerJars(ctx, config)
		jars := AllSystemServerJars(ctx, config)
		mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
			depIndex := android.IndexList(dep.Name(), jars)
			depIndex := jars.IndexOfJar(dep.Name())
			if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
				jar := jars[jarIndex]
				dep := jars[depIndex]
				jar := jars.Jar(jarIndex)
				dep := jars.Jar(depIndex)
				mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
					" '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
					" references from '%s' to '%s'.\n", jar, dep, jar, dep)
+45 −4
Original line number Diff line number Diff line
@@ -33,17 +33,35 @@ func testProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig
}

func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig {
	return createTestModuleConfig(
		name,
		fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
		android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
}

func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig {
	return createTestModuleConfig(
		name,
		fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name),
		android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
		android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
}

func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig {
	return &ModuleConfig{
		Name:                            name,
		DexLocation:                     fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
		BuildPath:                       android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
		DexPath:                         android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
		DexLocation:                     dexLocation,
		BuildPath:                       buildPath,
		DexPath:                         dexPath,
		UncompressedDex:                 false,
		HasApkLibraries:                 false,
		PreoptFlags:                     nil,
		ProfileClassListing:             android.OptionalPath{},
		ProfileIsTextListing:            false,
		EnforceUsesLibrariesStatusFile:  android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)),
		EnforceUsesLibrariesStatusFile:  enforceUsesLibrariesStatusFile,
		EnforceUsesLibraries:            false,
		ClassLoaderContexts:             nil,
		Archs:                           []android.ArchType{android.Arm},
@@ -140,6 +158,29 @@ func TestDexPreoptSystemOther(t *testing.T) {

}

func TestDexPreoptApexSystemServerJars(t *testing.T) {
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.BuilderContextForTesting(config)
	globalSoong := globalSoongConfigForTests()
	global := GlobalConfigForTests(ctx)
	module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")

	global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
		[]string{"com.android.apex1:service-A"})

	rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		t.Fatal(err)
	}

	wantInstalls := android.RuleBuilderInstalls{
		{android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
		{android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
	}

	android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
}

func TestDexPreoptProfile(t *testing.T) {
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.BuilderContextForTesting(config)
+7 −1
Original line number Diff line number Diff line
@@ -61,7 +61,13 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
	var entriesList []android.AndroidMkEntries

	if library.hideApexVariantFromMake {
		// For a java library built for an APEX we don't need Make module
		// For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
		// will conflict with the platform variant because they have the same module name in the
		// makefile. However, we need to add its dexpreopt outputs as sub-modules, if it is preopted.
		dexpreoptEntries := library.dexpreopter.AndroidMkEntriesForApex()
		if len(dexpreoptEntries) > 0 {
			entriesList = append(entriesList, dexpreoptEntries...)
		}
		entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
	} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
		// Platform variant.  If not available for the platform, we don't need Make module.
Loading