Merge "Populate individual classpath_fragments' classpaths.proto configs." into sc-dev
diff --git a/android/config.go b/android/config.go
index 79917ad..6dc8efe 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1618,6 +1618,21 @@
 	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 5d8a8e5..1064801 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -408,8 +408,16 @@
 }
 
 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 3724860..39a3e11 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 @@
 	"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 6ebeb6b..42bf0c2 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -203,18 +203,11 @@
 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 a505c6d..a72b3f6 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -47,24 +47,19 @@
 }
 
 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 @@
 		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 {