Merge changes I8f4eaed1,I358a62d3
* changes: Dexpreopt standalone system server jars from prebuilts. Dexpreopt standalone system server jars.
This commit is contained in:
@@ -1689,7 +1689,7 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
|
||||
}
|
||||
|
||||
// Append a list of (apex, jar) pairs to the list.
|
||||
func (l *ConfiguredJarList) AppendList(other ConfiguredJarList) ConfiguredJarList {
|
||||
func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
|
||||
apexes := make([]string, 0, l.Len()+other.Len())
|
||||
jars := make([]string, 0, l.Len()+other.Len())
|
||||
|
||||
|
@@ -8503,7 +8503,7 @@ func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) {
|
||||
java_import {
|
||||
name: "foo",
|
||||
jars: ["foo.jar"],
|
||||
installable: true,
|
||||
apex_available: ["myapex"],
|
||||
}
|
||||
`,
|
||||
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
|
||||
|
@@ -100,6 +100,48 @@ type GlobalConfig struct {
|
||||
RelaxUsesLibraryCheck bool
|
||||
}
|
||||
|
||||
var allPlatformSystemServerJarsKey = android.NewOnceKey("allPlatformSystemServerJars")
|
||||
|
||||
// Returns all jars on the platform that system_server loads, including those on classpath and those
|
||||
// loaded dynamically.
|
||||
func (g *GlobalConfig) AllPlatformSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
|
||||
return ctx.Config().Once(allPlatformSystemServerJarsKey, func() interface{} {
|
||||
res := g.SystemServerJars.AppendList(&g.StandaloneSystemServerJars)
|
||||
return &res
|
||||
}).(*android.ConfiguredJarList)
|
||||
}
|
||||
|
||||
var allApexSystemServerJarsKey = android.NewOnceKey("allApexSystemServerJars")
|
||||
|
||||
// Returns all jars delivered via apex that system_server loads, including those on classpath and
|
||||
// those loaded dynamically.
|
||||
func (g *GlobalConfig) AllApexSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
|
||||
return ctx.Config().Once(allApexSystemServerJarsKey, func() interface{} {
|
||||
res := g.ApexSystemServerJars.AppendList(&g.ApexStandaloneSystemServerJars)
|
||||
return &res
|
||||
}).(*android.ConfiguredJarList)
|
||||
}
|
||||
|
||||
var allSystemServerClasspathJarsKey = android.NewOnceKey("allSystemServerClasspathJars")
|
||||
|
||||
// Returns all system_server classpath jars.
|
||||
func (g *GlobalConfig) AllSystemServerClasspathJars(ctx android.PathContext) *android.ConfiguredJarList {
|
||||
return ctx.Config().Once(allSystemServerClasspathJarsKey, func() interface{} {
|
||||
res := g.SystemServerJars.AppendList(&g.ApexSystemServerJars)
|
||||
return &res
|
||||
}).(*android.ConfiguredJarList)
|
||||
}
|
||||
|
||||
var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
|
||||
|
||||
// Returns all jars that system_server loads.
|
||||
func (g *GlobalConfig) AllSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
|
||||
return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
|
||||
res := g.AllPlatformSystemServerJars(ctx).AppendList(g.AllApexSystemServerJars(ctx))
|
||||
return &res
|
||||
}).(*android.ConfiguredJarList)
|
||||
}
|
||||
|
||||
// GlobalSoongConfig contains the global config that is generated from Soong,
|
||||
// stored in dexpreopt_soong.config.
|
||||
type GlobalSoongConfig struct {
|
||||
|
@@ -115,7 +115,7 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo
|
||||
// /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.AllSystemServerJars(ctx).ContainsJar(module.Name) && !module.PreoptExtractedApk {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ func bootProfileCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig,
|
||||
}
|
||||
|
||||
// Returns the dex location of a system server java library.
|
||||
func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
|
||||
if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
|
||||
func GetSystemServerDexLocation(ctx android.PathContext, global *GlobalConfig, lib string) string {
|
||||
if apex := global.AllApexSystemServerJars(ctx).ApexOfJar(lib); apex != "" {
|
||||
return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
|
||||
}
|
||||
return fmt.Sprintf("/system/framework/%s.jar", lib)
|
||||
@@ -240,7 +240,8 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
|
||||
|
||||
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
|
||||
|
||||
systemServerJars := AllSystemServerJars(ctx, global)
|
||||
systemServerJars := global.AllSystemServerJars(ctx)
|
||||
systemServerClasspathJars := global.AllSystemServerClasspathJars(ctx)
|
||||
|
||||
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
|
||||
rule.Command().FlagWithOutput("rm -f ", odexPath)
|
||||
@@ -251,10 +252,15 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
|
||||
|
||||
var clcHost android.Paths
|
||||
var clcTarget []string
|
||||
for i := 0; i < jarIndex; i++ {
|
||||
lib := systemServerJars.Jar(i)
|
||||
endIndex := systemServerClasspathJars.IndexOfJar(module.Name)
|
||||
if endIndex < 0 {
|
||||
// The jar is a standalone one. Use the full classpath as the class loader context.
|
||||
endIndex = systemServerClasspathJars.Len()
|
||||
}
|
||||
for i := 0; i < endIndex; i++ {
|
||||
lib := systemServerClasspathJars.Jar(i)
|
||||
clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
|
||||
clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
|
||||
clcTarget = append(clcTarget, GetSystemServerDexLocation(ctx, global, lib))
|
||||
}
|
||||
|
||||
if DexpreoptRunningInSoong {
|
||||
@@ -270,12 +276,22 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
|
||||
// cannot see the rule in the generated dexpreopt.sh script).
|
||||
}
|
||||
|
||||
checkSystemServerOrder(ctx, jarIndex)
|
||||
clcHostString := "PCL[" + strings.Join(clcHost.Strings(), ":") + "]"
|
||||
clcTargetString := "PCL[" + strings.Join(clcTarget, ":") + "]"
|
||||
|
||||
if systemServerClasspathJars.ContainsJar(module.Name) {
|
||||
checkSystemServerOrder(ctx, jarIndex)
|
||||
} else {
|
||||
// Standalone jars are loaded by separate class loaders with SYSTEMSERVERCLASSPATH as the
|
||||
// parent.
|
||||
clcHostString = "PCL[];" + clcHostString
|
||||
clcTargetString = "PCL[];" + clcTargetString
|
||||
}
|
||||
|
||||
rule.Command().
|
||||
Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(clcHost.Strings(), ":") + "]").
|
||||
Text(`class_loader_context_arg=--class-loader-context="` + clcHostString + `"`).
|
||||
Implicits(clcHost).
|
||||
Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clcTarget, ":") + "]")
|
||||
Text(`stored_class_loader_context_arg=--stored-class-loader-context="` + clcTargetString + `"`)
|
||||
|
||||
} else {
|
||||
// There are three categories of Java modules handled here:
|
||||
@@ -533,17 +549,6 @@ func makefileMatch(pattern, s string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// A predefined location for the system server dex jars. This is needed in order to generate
|
||||
// class loader context for dex2oat, as the path to the jar in the Soong module may be unknown
|
||||
// at that time (Soong processes the jars in dependency order, which may be different from the
|
||||
@@ -567,7 +572,7 @@ func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
|
||||
mctx, isModule := ctx.(android.ModuleContext)
|
||||
if isModule {
|
||||
config := GetGlobalConfig(ctx)
|
||||
jars := AllSystemServerJars(ctx, config)
|
||||
jars := config.AllSystemServerClasspathJars(ctx)
|
||||
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
|
||||
depIndex := jars.IndexOfJar(dep.Name())
|
||||
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
|
||||
|
@@ -50,6 +50,15 @@ func testApexModuleConfig(ctx android.PathContext, name, apexName string) *Modul
|
||||
android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
|
||||
}
|
||||
|
||||
func testPlatformSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
|
||||
return createTestModuleConfig(
|
||||
name,
|
||||
fmt.Sprintf("/system/framework/%s.jar", 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,
|
||||
@@ -181,6 +190,52 @@ func TestDexPreoptApexSystemServerJars(t *testing.T) {
|
||||
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
|
||||
}
|
||||
|
||||
func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
|
||||
config := android.TestConfig("out", nil, "", nil)
|
||||
ctx := android.BuilderContextForTesting(config)
|
||||
globalSoong := globalSoongConfigForTests()
|
||||
global := GlobalConfigForTests(ctx)
|
||||
module := testPlatformSystemServerModuleConfig(ctx, "service-A")
|
||||
|
||||
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
|
||||
[]string{"platform: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/service-A.odex"},
|
||||
{android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/service-A.vdex"},
|
||||
}
|
||||
|
||||
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
|
||||
}
|
||||
|
||||
func TestDexPreoptApexStandaloneSystemServerJars(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.ApexStandaloneSystemServerJars = 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)
|
||||
|
@@ -182,7 +182,14 @@ func (j *TestHelperLibrary) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
}
|
||||
|
||||
func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
if prebuilt.hideApexVariantFromMake || !prebuilt.ContainingSdk().Unversioned() {
|
||||
if prebuilt.hideApexVariantFromMake {
|
||||
// For a library imported from a prebuilt APEX, we don't need a Make module for itself, as we
|
||||
// don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
|
||||
// is preopted.
|
||||
dexpreoptEntries := prebuilt.dexpreopter.AndroidMkEntriesForApex()
|
||||
return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
|
||||
}
|
||||
if !prebuilt.ContainingSdk().Unversioned() {
|
||||
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
||||
Disabled: true,
|
||||
}}
|
||||
|
@@ -115,6 +115,11 @@ func isApexVariant(ctx android.BaseModuleContext) bool {
|
||||
return !apexInfo.IsForPlatform()
|
||||
}
|
||||
|
||||
func forPrebuiltApex(ctx android.BaseModuleContext) bool {
|
||||
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||
return apexInfo.ForPrebuiltApex
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -134,7 +139,9 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if !ctx.Module().(DexpreopterInterface).IsInstallable() {
|
||||
// If the module is from a prebuilt APEX, it shouldn't be installable, but it can still be
|
||||
// dexpreopted.
|
||||
if !ctx.Module().(DexpreopterInterface).IsInstallable() && !forPrebuiltApex(ctx) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -152,15 +159,16 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
|
||||
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() {
|
||||
if !isApexSystemServerJar || 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)) {
|
||||
if isApexSystemServerJar {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -191,8 +199,8 @@ func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath a
|
||||
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))
|
||||
if global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) {
|
||||
dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, moduleName(ctx))
|
||||
return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/"))
|
||||
}
|
||||
if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) &&
|
||||
@@ -229,8 +237,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
|
||||
return
|
||||
}
|
||||
|
||||
isSystemServerJar := global.SystemServerJars.ContainsJar(moduleName(ctx)) ||
|
||||
global.ApexSystemServerJars.ContainsJar(moduleName(ctx))
|
||||
isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx))
|
||||
|
||||
bootImage := defaultBootImageConfig(ctx)
|
||||
if global.UseArtImage {
|
||||
@@ -336,6 +343,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
|
||||
|
||||
dexpreoptRule.Build("dexpreopt", "dexpreopt")
|
||||
|
||||
isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
|
||||
|
||||
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), "/")
|
||||
@@ -343,7 +352,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
|
||||
arch := filepath.Base(installDir)
|
||||
installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir)
|
||||
|
||||
if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
|
||||
if isApexSystemServerJar {
|
||||
// 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.
|
||||
@@ -362,7 +371,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
|
||||
}
|
||||
}
|
||||
|
||||
if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
|
||||
if !isApexSystemServerJar {
|
||||
d.builtInstalled = dexpreoptRule.Installs().String()
|
||||
}
|
||||
}
|
||||
|
@@ -72,9 +72,10 @@ func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.Mod
|
||||
return
|
||||
}
|
||||
|
||||
systemServerJars := dexpreopt.AllSystemServerJars(ctx, global)
|
||||
// TODO(b/203198541): Check all system server jars.
|
||||
systemServerJars := global.AllSystemServerClasspathJars(ctx)
|
||||
for _, jar := range systemServerJars.CopyOfJars() {
|
||||
dexLocation := dexpreopt.GetSystemServerDexLocation(global, jar)
|
||||
dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, jar)
|
||||
odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType)
|
||||
odexPath := getInstallPath(ctx, odexLocation)
|
||||
vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex"))
|
||||
|
@@ -60,7 +60,7 @@ func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx an
|
||||
classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType)
|
||||
standaloneConfiguredJars := p.standaloneConfiguredJars(ctx)
|
||||
standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
|
||||
configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
|
||||
configuredJars = configuredJars.AppendList(&standaloneConfiguredJars)
|
||||
classpathJars = append(classpathJars, standaloneClasspathJars...)
|
||||
p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||
classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType)
|
||||
standaloneConfiguredJars := s.standaloneConfiguredJars(ctx)
|
||||
standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
|
||||
configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
|
||||
configuredJars = configuredJars.AppendList(&standaloneConfiguredJars)
|
||||
classpathJars = append(classpathJars, standaloneClasspathJars...)
|
||||
s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
|
||||
|
||||
|
Reference in New Issue
Block a user