Restore checkSystemServerOrder

Move checkSystemServerOrder into the java package so it can filter out
bootclasspathDependencyTag dependencies in order to prevent traversing
into bootclasspath dependencies and confusing them with system server
classpath dependencies.

Bug: 397461231
Test: TestCheckSystemServerOrderWithArtApex
Change-Id: I64630eb2edfcffe796cc5eb47c08ed167a6ff0dd
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 5755dec..b21cfc9 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -565,6 +565,10 @@
 	if !isApexSystemServerJar {
 		d.builtInstalled = dexpreoptRule.Installs().String()
 	}
+
+	if isSystemServerJar {
+		checkSystemServerOrder(ctx, libName)
+	}
 }
 
 func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) {
@@ -631,3 +635,30 @@
 func (d *dexpreopter) SetRewrittenProfile(p android.Path) {
 	d.rewrittenProfile = p
 }
+
+// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
+// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
+// have the dependency jar in the class loader context, and it won't be able to resolve any
+// references to its classes and methods.
+func checkSystemServerOrder(ctx android.ModuleContext, libName string) {
+	config := dexpreopt.GetGlobalConfig(ctx)
+	jars := config.AllSystemServerClasspathJars(ctx)
+	jarIndex := config.AllSystemServerJars(ctx).IndexOfJar(libName)
+	ctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+		tag := ctx.OtherModuleDependencyTag(dep)
+		// Ideally this should only be walking relevant dependencies, but to maintain existing behavior
+		// for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
+		if _, ok := tag.(bootclasspathDependencyTag); ok {
+			return false
+		}
+		depIndex := jars.IndexOfJar(dep.Name())
+		if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
+			jar := jars.Jar(jarIndex)
+			dep := jars.Jar(depIndex)
+			ctx.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)
+		}
+		return true
+	})
+}