From 92346c483249726164f4bd140413d60391121763 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 15 Sep 2021 14:11:07 +0000 Subject: [PATCH] Revert "Preopt APEX system server jars." This reverts commit ca9bc98e0cfe9a519cfdd13450a68f1ed7ad5b02. Reason for revert: breaks build Bug: 200024131 Change-Id: Ide07b4c4d267370ae31107b1598b2f878c701282 --- android/config.go | 14 --- apex/apex.go | 5 - dexpreopt/dexpreopt.go | 54 ++++----- dexpreopt/dexpreopt_test.go | 49 +------- java/androidmk.go | 8 +- java/dexpreopt.go | 160 +++---------------------- java/dexpreopt_test.go | 227 +----------------------------------- java/java.go | 13 +-- java/testing.go | 42 ------- 9 files changed, 54 insertions(+), 518 deletions(-) diff --git a/android/config.go b/android/config.go index 993aaa779..3e41fbb4f 100644 --- a/android/config.go +++ b/android/config.go @@ -1659,20 +1659,6 @@ 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()) diff --git a/apex/apex.go b/apex/apex.go index 2d153e2c0..e3edc681d 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1569,11 +1569,6 @@ 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 } diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index 7733c1b43..1401c75d9 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -110,12 +110,17 @@ 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) && - !AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk { + !global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk { return true } @@ -196,14 +201,6 @@ 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) { @@ -219,13 +216,6 @@ 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", @@ -244,21 +234,20 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g invocationPath := odexPath.ReplaceExtension(ctx, "invocation") - systemServerJars := AllSystemServerJars(ctx, global) + systemServerJars := NonApexSystemServerJars(ctx, global) rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String())) rule.Command().FlagWithOutput("rm -f ", odexPath) - if jarIndex := systemServerJars.IndexOfJar(module.Name); jarIndex >= 0 { + if jarIndex := android.IndexList(module.Name, systemServerJars); 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 i := 0; i < jarIndex; i++ { - lib := systemServerJars.Jar(i) + for _, lib := range systemServerJars[:jarIndex] { clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib)) - clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib)) + clcTarget = append(clcTarget, filepath.Join("/system/framework", lib+".jar")) } // Copy the system server jar to a predefined location where dex2oat will find it. @@ -373,7 +362,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g if !android.PrefixInList(preoptFlags, "--compiler-filter=") { var compilerFilter string - if systemServerJars.ContainsJar(module.Name) { + if global.SystemServerJars.ContainsJar(module.Name) { // Jars of system server, use the product option if it is set, speed otherwise. if global.SystemServerCompilerFilter != "" { compilerFilter = global.SystemServerCompilerFilter @@ -427,7 +416,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 systemServerJars.ContainsJar(module.Name) { + if global.SystemServerJars.ContainsJar(module.Name) { if global.AlwaysSystemServerDebugInfo { debugInfo = true } else if global.NeverSystemServerDebugInfo { @@ -529,15 +518,14 @@ func makefileMatch(pattern, s string) bool { } } -var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars") +var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars") // TODO: eliminate the superficial global config parameter by moving global config definition // from java subpackage to dexpreopt. -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) +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) } // A predefined location for the system server dex jars. This is needed in order to generate @@ -563,12 +551,12 @@ func checkSystemServerOrder(ctx android.PathContext, jarIndex int) { mctx, isModule := ctx.(android.ModuleContext) if isModule { config := GetGlobalConfig(ctx) - jars := AllSystemServerJars(ctx, config) + jars := NonApexSystemServerJars(ctx, config) mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { - depIndex := jars.IndexOfJar(dep.Name()) + depIndex := android.IndexList(dep.Name(), jars) if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars { - jar := jars.Jar(jarIndex) - dep := jars.Jar(depIndex) + jar := jars[jarIndex] + dep := jars[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) diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go index 798d77604..4ee61b6b0 100644 --- a/dexpreopt/dexpreopt_test.go +++ b/dexpreopt/dexpreopt_test.go @@ -33,35 +33,17 @@ 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: dexLocation, - BuildPath: buildPath, - DexPath: dexPath, + 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)), UncompressedDex: false, HasApkLibraries: false, PreoptFlags: nil, ProfileClassListing: android.OptionalPath{}, ProfileIsTextListing: false, - EnforceUsesLibrariesStatusFile: enforceUsesLibrariesStatusFile, + EnforceUsesLibrariesStatusFile: android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)), EnforceUsesLibraries: false, ClassLoaderContexts: nil, Archs: []android.ArchType{android.Arm}, @@ -158,29 +140,6 @@ 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) diff --git a/java/androidmk.go b/java/androidmk.go index 71370c9b1..68ccd82e9 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -61,13 +61,7 @@ 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 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...) - } + // For a java library built for an APEX we don't need Make module 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. diff --git a/java/dexpreopt.go b/java/dexpreopt.go index cdd42ed1a..0faae36ba 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -15,46 +15,13 @@ package java import ( - "path/filepath" - "strings" - "android/soong/android" "android/soong/dexpreopt" ) -type DexpreopterInterface interface { +type dexpreopterInterface interface { IsInstallable() bool // Structs that embed dexpreopter must implement this. dexpreoptDisabled(ctx android.BaseModuleContext) bool - DexpreoptBuiltInstalledForApex() []dexpreopterInstall - AndroidMkEntriesForApex() []android.AndroidMkEntries -} - -type dexpreopterInstall struct { - // A unique name to distinguish an output from others for the same java library module. Usually in - // the form of `-.odex/vdex/art`. - name string - - // The name of the input java module. - moduleName string - - // The path to the dexpreopt output on host. - outputPathOnHost android.Path - - // The directory on the device for the output to install to. - installDirOnDevice android.InstallPath - - // The basename (the last segment of the path) for the output to install as. - installFileOnDevice string -} - -// The full module name of the output in the makefile. -func (install *dexpreopterInstall) FullModuleName() string { - return install.moduleName + install.SubModuleName() -} - -// The sub-module name of the output in the makefile (the name excluding the java module name). -func (install *dexpreopterInstall) SubModuleName() string { - return "-dexpreopt-" + install.name } type dexpreopter struct { @@ -72,9 +39,7 @@ type dexpreopter struct { enforceUsesLibs bool classLoaderContexts dexpreopt.ClassLoaderContextMap - // See the `dexpreopt` function for details. - builtInstalled string - builtInstalledForApex []dexpreopterInstall + builtInstalled string // The config is used for two purposes: // - Passing dexpreopt information about libraries from Soong to Make. This is needed when @@ -109,17 +74,6 @@ func init() { dexpreopt.DexpreoptRunningInSoong = true } -func isApexVariant(ctx android.BaseModuleContext) bool { - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - return !apexInfo.IsForPlatform() -} - -func moduleName(ctx android.BaseModuleContext) string { - // Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not - // expected by dexpreopter. - return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()) -} - func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { global := dexpreopt.GetGlobalConfig(ctx) @@ -127,7 +81,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { return true } - if inList(moduleName(ctx), global.DisablePreoptModules) { + if inList(ctx.ModuleName(), global.DisablePreoptModules) { return true } @@ -139,7 +93,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { return true } - if !ctx.Module().(DexpreopterInterface).IsInstallable() { + if !ctx.Module().(dexpreopterInterface).IsInstallable() { return true } @@ -147,17 +101,9 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { return true } - if isApexVariant(ctx) { - // Don't preopt APEX variant module unless the module is an APEX system server jar and we are - // building the entire system image. - if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) || ctx.Config().UnbundledBuild() { - return true - } - } else { - // Don't preopt the platform variant of an APEX system server jar to avoid conflicts. - if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) { - return true - } + // Don't preopt APEX variant module + if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { + return true } // TODO: contains no java code @@ -166,40 +112,17 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { } func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) { - if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) { + if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) { return } dexpreopt.RegisterToolDeps(ctx) } -func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool { - return dexpreopt.OdexOnSystemOtherByName(moduleName(ctx), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx)) -} - -// Returns the install path of the dex jar of a module. -// -// Do not rely on `ApexInfo.ApexVariationName` because it can be something like "apex1000", rather -// than the `name` in the path `/apex/` as suggested in its comment. -// -// This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a -// system server jar, which is fine because we currently only preopt system server jars for APEXes. -func (d *dexpreopter) getInstallPath( - ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath { - global := dexpreopt.GetGlobalConfig(ctx) - if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) { - dexLocation := dexpreopt.GetSystemServerDexLocation(global, moduleName(ctx)) - return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/")) - } - if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) && - filepath.Base(defaultInstallPath.PartitionDir()) != "apex" { - ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt") - } - return defaultInstallPath +func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool { + return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx)) } func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) { - global := dexpreopt.GetGlobalConfig(ctx) - // TODO(b/148690468): The check on d.installPath is to bail out in cases where // the dexpreopter struct hasn't been fully initialized before we're called, // e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively @@ -210,7 +133,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath) - providesUsesLib := moduleName(ctx) + providesUsesLib := ctx.ModuleName() if ulib, ok := ctx.Module().(ProvidesUsesLib); ok { name := ulib.ProvidesUsesLib() if name != nil { @@ -224,8 +147,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr return } - isSystemServerJar := global.SystemServerJars.ContainsJar(moduleName(ctx)) || - global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) + global := dexpreopt.GetGlobalConfig(ctx) + + isSystemServerJar := global.SystemServerJars.ContainsJar(ctx.ModuleName()) bootImage := defaultBootImageConfig(ctx) if global.UseArtImage { @@ -275,15 +199,15 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr profileIsTextListing = true } else if global.ProfileDir != "" { profileClassListing = android.ExistentPathForSource(ctx, - global.ProfileDir, moduleName(ctx)+".prof") + global.ProfileDir, ctx.ModuleName()+".prof") } } // Full dexpreopt config, used to create dexpreopt build rules. dexpreoptConfig := &dexpreopt.ModuleConfig{ - Name: moduleName(ctx), + Name: ctx.ModuleName(), DexLocation: dexLocation, - BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath, + BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath, DexPath: dexJarFile, ManifestPath: android.OptionalPathForPath(d.manifestFile), UncompressedDex: d.uncompressedDex, @@ -332,53 +256,5 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr dexpreoptRule.Build("dexpreopt", "dexpreopt") - if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) { - // APEX variants of java libraries are hidden from Make, so their dexpreopt outputs need special - // handling. Currently, for APEX variants of java libraries, only those in the system server - // classpath are handled here. Preopting of boot classpath jars in the ART APEX are handled in - // java/dexpreopt_bootjars.go, and other APEX jars are not preopted. - for _, install := range dexpreoptRule.Installs() { - // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. - installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") - installBase := filepath.Base(install.To) - arch := filepath.Base(installDir) - installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir) - // The installs will be handled by Make as sub-modules of the java library. - d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{ - name: arch + "-" + installBase, - moduleName: moduleName(ctx), - outputPathOnHost: install.From, - installDirOnDevice: installPath, - installFileOnDevice: installBase, - }) - } - } else { - // The installs will be handled by Make as LOCAL_SOONG_BUILT_INSTALLED of the java library - // module. - d.builtInstalled = dexpreoptRule.Installs().String() - } -} - -func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall { - return d.builtInstalledForApex -} - -func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries { - var entries []android.AndroidMkEntries - for _, install := range d.builtInstalledForApex { - install := install - entries = append(entries, android.AndroidMkEntries{ - Class: "ETC", - SubName: install.SubModuleName(), - OutputFile: android.OptionalPathForPath(install.outputPathOnHost), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.ToMakePath().String()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) - entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") - }, - }, - }) - } - return entries + d.builtInstalled = dexpreoptRule.Installs().String() } diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index 1c1070add..8dc7b798a 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -17,7 +17,6 @@ package java import ( "fmt" "runtime" - "strings" "testing" "android/soong/android" @@ -25,17 +24,11 @@ import ( "android/soong/dexpreopt" ) -func init() { - RegisterFakeRuntimeApexMutator() -} - func TestDexpreoptEnabled(t *testing.T) { tests := []struct { - name string - bp string - moduleName string - apexVariant bool - enabled bool + name string + bp string + enabled bool }{ { name: "app", @@ -155,81 +148,13 @@ func TestDexpreoptEnabled(t *testing.T) { }`, enabled: true, }, - { - name: "apex variant", - bp: ` - java_library { - name: "foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`, - apexVariant: true, - enabled: false, - }, - { - name: "apex variant of apex system server jar", - bp: ` - java_library { - name: "service-foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`, - moduleName: "service-foo", - apexVariant: true, - enabled: true, - }, - { - name: "apex variant of prebuilt apex system server jar", - bp: ` - java_library { - name: "prebuilt_service-foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`, - moduleName: "prebuilt_service-foo", - apexVariant: true, - enabled: true, - }, - { - name: "platform variant of apex system server jar", - bp: ` - java_library { - name: "service-foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`, - moduleName: "service-foo", - apexVariant: false, - enabled: false, - }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - preparers := android.GroupFixturePreparers( - PrepareForTestWithJavaDefaultModules, - PrepareForTestWithFakeApexMutator, - dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), - ) + ctx, _ := testJava(t, test.bp) - result := preparers.RunTestWithBp(t, test.bp) - ctx := result.TestContext - - moduleName := "foo" - if test.moduleName != "" { - moduleName = test.moduleName - } - - variant := "android_common" - if test.apexVariant { - variant += "_apex1000" - } - - dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt") + dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt") enabled := dexpreopt.Rule != nil if enabled != test.enabled { @@ -295,145 +220,3 @@ func TestDex2oatToolDeps(t *testing.T) { testDex2oatToolDep(true, true, true, prebuiltDex2oatPath) testDex2oatToolDep(false, true, false, prebuiltDex2oatPath) } - -func TestDexpreoptBuiltInstalledForApex(t *testing.T) { - preparers := android.GroupFixturePreparers( - PrepareForTestWithJavaDefaultModules, - PrepareForTestWithFakeApexMutator, - dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), - ) - - // An APEX system server jar. - result := preparers.RunTestWithBp(t, ` - java_library { - name: "service-foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`) - ctx := result.TestContext - module := ctx.ModuleForTests("service-foo", "android_common_apex1000") - library := module.Module().(*Library) - - installs := library.dexpreopter.DexpreoptBuiltInstalledForApex() - - android.AssertIntEquals(t, "install count", 2, len(installs)) - - android.AssertStringEquals(t, "installs[0] FullModuleName", - "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", - installs[0].FullModuleName()) - - android.AssertStringEquals(t, "installs[0] SubModuleName", - "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", - installs[0].SubModuleName()) - - android.AssertStringEquals(t, "installs[1] FullModuleName", - "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", - installs[1].FullModuleName()) - - android.AssertStringEquals(t, "installs[1] SubModuleName", - "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", - installs[1].SubModuleName()) - - // Not an APEX system server jar. - result = preparers.RunTestWithBp(t, ` - java_library { - name: "foo", - installable: true, - srcs: ["a.java"], - }`) - ctx = result.TestContext - module = ctx.ModuleForTests("foo", "android_common") - library = module.Module().(*Library) - - installs = library.dexpreopter.DexpreoptBuiltInstalledForApex() - - android.AssertIntEquals(t, "install count", 0, len(installs)) -} - -func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries { - var results []android.AndroidMkEntries - for _, entries := range entriesList { - if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") { - results = append(results, entries) - } - } - return results -} - -func verifyEntries(t *testing.T, message string, expectedModule string, - expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string, - entries android.AndroidMkEntries) { - android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule, - entries.EntryMap["LOCAL_MODULE"][0]) - - android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC", - entries.EntryMap["LOCAL_MODULE_CLASS"][0]) - - android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE", - entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile) - - android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH", - entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath) - - android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM", - expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0]) - - android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM", - "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0]) -} - -func TestAndroidMkEntriesForApex(t *testing.T) { - preparers := android.GroupFixturePreparers( - PrepareForTestWithJavaDefaultModules, - PrepareForTestWithFakeApexMutator, - dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), - ) - - // An APEX system server jar. - result := preparers.RunTestWithBp(t, ` - java_library { - name: "service-foo", - installable: true, - srcs: ["a.java"], - apex_available: ["com.android.apex1"], - }`) - ctx := result.TestContext - module := ctx.ModuleForTests("service-foo", "android_common_apex1000") - - entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module()) - entriesList = filterDexpreoptEntriesList(entriesList) - - android.AssertIntEquals(t, "entries count", 2, len(entriesList)) - - verifyEntries(t, - "entriesList[0]", - "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", - "/dexpreopt/oat/arm64/javalib.odex", - "/system/framework/oat/arm64", - "apex@com.android.apex1@javalib@service-foo.jar@classes.odex", - entriesList[0]) - - verifyEntries(t, - "entriesList[1]", - "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", - "/dexpreopt/oat/arm64/javalib.vdex", - "/system/framework/oat/arm64", - "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", - entriesList[1]) - - // Not an APEX system server jar. - result = preparers.RunTestWithBp(t, ` - java_library { - name: "foo", - installable: true, - srcs: ["a.java"], - }`) - ctx = result.TestContext - module = ctx.ModuleForTests("foo", "android_common") - - entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module()) - entriesList = filterDexpreoptEntriesList(entriesList) - - android.AssertIntEquals(t, "entries count", 0, len(entriesList)) -} diff --git a/java/java.go b/java/java.go index e2665ef04..1a052b432 100644 --- a/java/java.go +++ b/java/java.go @@ -487,7 +487,7 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo } // Store uncompressed dex files that are preopted on /system. - if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) { + if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) { return true } if ctx.Config().UncompressPrivAppDex() && @@ -508,8 +508,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.checkSdkVersions(ctx) - j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary if j.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. @@ -1369,8 +1368,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Dex compilation - j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", jarName)) + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName) if j.dexProperties.Uncompress_dex == nil { // If the value was not force-set by the user, use reasonable default based on the module. j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) @@ -1511,7 +1509,7 @@ func (j *Import) IsInstallable() bool { return Bool(j.properties.Installable) } -var _ DexpreopterInterface = (*Import)(nil) +var _ dexpreopterInterface = (*Import)(nil) // java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. // @@ -1624,8 +1622,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.hideApexVariantFromMake = true } - j.dexpreopter.installPath = j.dexpreopter.getInstallPath( - ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") diff --git a/java/testing.go b/java/testing.go index d8a77cf37..8860b45fa 100644 --- a/java/testing.go +++ b/java/testing.go @@ -431,45 +431,3 @@ func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, mes output := sourceGlobalCompatConfig.Output(allOutputs[0]) android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) } - -// Register the fake APEX mutator to `android.InitRegistrationContext` as if the real mutator exists -// at runtime. This must be called in `init()` of a test if the test is going to use the fake APEX -// mutator. Otherwise, we will be missing the runtime mutator because "soong-apex" is not a -// dependency, which will cause an inconsistency between testing and runtime mutators. -func RegisterFakeRuntimeApexMutator() { - registerFakeApexMutator(android.InitRegistrationContext) -} - -var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers( - android.FixtureRegisterWithContext(registerFakeApexMutator), -) - -func registerFakeApexMutator(ctx android.RegistrationContext) { - ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("apex", fakeApexMutator).Parallel() - }) -} - -type apexModuleBase interface { - ApexAvailable() []string -} - -var _ apexModuleBase = (*Library)(nil) -var _ apexModuleBase = (*SdkLibrary)(nil) - -// A fake APEX mutator that creates a platform variant and an APEX variant for modules with -// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex", -// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for -// testing without dealing with all the complexities in the real mutator. -func fakeApexMutator(mctx android.BottomUpMutatorContext) { - switch mctx.Module().(type) { - case *Library, *SdkLibrary: - if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 { - modules := mctx.CreateVariations("", "apex1000") - apexInfo := android.ApexInfo{ - ApexVariationName: "apex1000", - } - mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo) - } - } -}