From 95bfbb169fa86053f718e8b02c2d101262cab59a Mon Sep 17 00:00:00 2001 From: satayev Date: Thu, 20 May 2021 11:24:00 +0100 Subject: [PATCH] Populate individual classpath_fragments' classpaths.proto configs. To avoid duplicates on *CLASSPATH environ variables at runtime, remove split entries from platform-*classpath, i.e. all updatable jars that have their own classpath fragments should not appear in the platform-*classpath's classpaths.proto config. Bug: 180105615 Test: m && launch_cvd; atest CtsClasspathsTestCases Change-Id: Id2759ab8e106cc183e695bf3509a6ab60ab0ef2a --- android/config.go | 15 ++++++++++++++ java/bootclasspath_fragment.go | 12 +++++++++-- java/dexpreopt_config.go | 27 ------------------------- java/platform_bootclasspath.go | 9 +-------- java/systemserver_classpath_fragment.go | 26 ++++++++++-------------- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/android/config.go b/android/config.go index 79917adf4..6dc8efe25 100644 --- a/android/config.go +++ b/android/config.go @@ -1618,6 +1618,21 @@ func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList return ConfiguredJarList{apexes, jars} } +// Filter keeps the entries if a jar appears in the given list of jars to keep; returns a new list. +func (l *ConfiguredJarList) Filter(jarsToKeep []string) ConfiguredJarList { + var apexes []string + var jars []string + + for i, jar := range l.jars { + if InList(jar, jarsToKeep) { + apexes = append(apexes, l.apexes[i]) + jars = append(jars, jar) + } + } + + return ConfiguredJarList{apexes, jars} +} + // CopyOfJars returns a copy of the list of strings containing jar module name // components. func (l *ConfiguredJarList) CopyOfJars() []string { diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 5d8a8e525..10648016c 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -408,8 +408,16 @@ func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx and } func (b *BootclasspathFragmentModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList { - // TODO(satayev): populate with actual content - return android.EmptyConfiguredJarList() + if "art" == proptools.String(b.properties.Image_name) { + return b.getImageConfig(ctx).modules + } + + global := dexpreopt.GetGlobalConfig(ctx) + + // Only create configs for updatable boot jars. Non-updatable boot jars must be part of the + // platform_bootclasspath's classpath proto config to guarantee that they come before any + // updatable jars at runtime. + return global.UpdatableBootJars.Filter(b.properties.Contents) } func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig { diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 37248609d..39a3e11a5 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -15,7 +15,6 @@ package java import ( - "fmt" "path/filepath" "strings" @@ -23,32 +22,6 @@ import ( "android/soong/dexpreopt" ) -// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed -// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same -// ctx.Config(). -func systemServerClasspath(ctx android.PathContext) []string { - return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { - global := dexpreopt.GetGlobalConfig(ctx) - var systemServerClasspathLocations []string - nonUpdatable := dexpreopt.NonUpdatableSystemServerJars(ctx, global) - // 1) Non-updatable jars. - for _, m := range nonUpdatable { - systemServerClasspathLocations = append(systemServerClasspathLocations, - filepath.Join("/system/framework", m+".jar")) - } - // 2) The jars that are from an updatable apex. - systemServerClasspathLocations = append(systemServerClasspathLocations, - global.UpdatableSystemServerJars.DevicePaths(ctx.Config(), android.Android)...) - - if expectedLen := global.SystemServerJars.Len() + global.UpdatableSystemServerJars.Len(); expectedLen != len(systemServerClasspathLocations) { - panic(fmt.Errorf("wrong number of system server jars, got %d, expected %d", len(systemServerClasspathLocations), expectedLen)) - } - return systemServerClasspathLocations - }) -} - -var systemServerClasspathKey = android.NewOnceKey("systemServerClasspath") - // dexpreoptTargets returns the list of targets that are relevant to dexpreopting, which excludes architectures // supported through native bridge. func dexpreoptTargets(ctx android.PathContext) []android.Target { diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 6ebeb6b89..42bf0c238 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -203,18 +203,11 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo func (b *platformBootclasspathModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) { // ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH classpathJars := configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH) - - // TODO(satayev): remove updatable boot jars once each apex has its own fragment - global := dexpreopt.GetGlobalConfig(ctx) - classpathJars = append(classpathJars, configuredJarListToClasspathJars(ctx, global.UpdatableBootJars, BOOTCLASSPATH)...) - b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars) } func (b *platformBootclasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList { - global := dexpreopt.GetGlobalConfig(ctx) - // TODO(satayev): split ART apex jars into their own classpathFragment - return global.BootJars + return b.getImageConfig(ctx).modules } // checkNonUpdatableModules ensures that the non-updatable modules supplied are not part of an diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index a505c6d01..a72b3f60c 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -47,24 +47,19 @@ func (p *platformSystemServerClasspathModule) AndroidMkEntries() (entries []andr } func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - configuredJars := configuredJarListToClasspathJars(ctx, p.ClasspathFragmentToConfiguredJarList(ctx), p.classpathType) - p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars) + classpathJars := configuredJarListToClasspathJars(ctx, p.ClasspathFragmentToConfiguredJarList(ctx), p.classpathType) + p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars) } -var platformSystemServerClasspathKey = android.NewOnceKey("platform_systemserverclasspath") - func (p *platformSystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList { - return ctx.Config().Once(platformSystemServerClasspathKey, func() interface{} { - global := dexpreopt.GetGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) - jars := global.SystemServerJars - - // TODO(satayev): split apex jars into separate configs. - for i := 0; i < global.UpdatableSystemServerJars.Len(); i++ { - jars = jars.Append(global.UpdatableSystemServerJars.Apex(i), global.UpdatableSystemServerJars.Jar(i)) - } - return jars - }).(android.ConfiguredJarList) + jars := global.SystemServerJars + // TODO(satayev): split apex jars into separate configs. + for i := 0; i < global.UpdatableSystemServerJars.Len(); i++ { + jars = jars.Append(global.UpdatableSystemServerJars.Apex(i), global.UpdatableSystemServerJars.Jar(i)) + } + return jars } type SystemServerClasspathModule struct { @@ -101,7 +96,8 @@ func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.Mo ctx.PropertyErrorf("contents", "empty contents are not allowed") } - s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJarListToClasspathJars(ctx, s.ClasspathFragmentToConfiguredJarList(ctx))) + classpathJars := configuredJarListToClasspathJars(ctx, s.ClasspathFragmentToConfiguredJarList(ctx), s.classpathType) + s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars) } func (s *SystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {