Propagate java resources in apps with no code

Use the java resources jar as the dex jar when building apps that
have no code.

Also remove maybeStrippedDexJar, the dex jar is never stripped now.

Fixes: 176305357
Test: TestAppJavaResources
Change-Id: Ic8b1165bd35d71237d307e7f5f895764e203a10d
diff --git a/java/androidmk.go b/java/androidmk.go
index 9bdb70c..3d3eae5 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -220,7 +220,7 @@
 	}
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "JAVA_LIBRARIES",
-		OutputFile: android.OptionalPathForPath(prebuilt.maybeStrippedDexJarFile),
+		OutputFile: android.OptionalPathForPath(prebuilt.dexJarFile),
 		Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
diff --git a/java/app.go b/java/app.go
index 8287533..39f06d0 100755
--- a/java/app.go
+++ b/java/app.go
@@ -469,7 +469,7 @@
 		a.Module.compile(ctx, a.aaptSrcJar)
 	}
 
-	return a.maybeStrippedDexJarFile
+	return a.dexJarFile
 }
 
 func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, ctx android.ModuleContext) android.WritablePath {
diff --git a/java/app_test.go b/java/app_test.go
index b1abe3d..349579e 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -685,6 +685,51 @@
 	}
 }
 
+func TestAppJavaResources(t *testing.T) {
+	bp := `
+			android_app {
+				name: "foo",
+				sdk_version: "current",
+				java_resources: ["resources/a"],
+				srcs: ["a.java"],
+			}
+
+			android_app {
+				name: "bar",
+				sdk_version: "current",
+				java_resources: ["resources/a"],
+			}
+		`
+
+	ctx := testApp(t, bp)
+
+	foo := ctx.ModuleForTests("foo", "android_common")
+	fooResources := foo.Output("res/foo.jar")
+	fooDexJar := foo.Output("dex-withres/foo.jar")
+	fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
+	fooApk := foo.Rule("combineApk")
+
+	if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
+		t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
+	}
+
+	if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
+		t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
+	}
+
+	if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
+		t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
+	}
+
+	bar := ctx.ModuleForTests("bar", "android_common")
+	barResources := bar.Output("res/bar.jar")
+	barApk := bar.Rule("combineApk")
+
+	if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
+		t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
+	}
+}
+
 func TestAndroidResources(t *testing.T) {
 	testCases := []struct {
 		name                       string
diff --git a/java/java.go b/java/java.go
index 78cd362..698c5b9 100644
--- a/java/java.go
+++ b/java/java.go
@@ -434,9 +434,6 @@
 	// output file containing classes.dex and resources
 	dexJarFile android.Path
 
-	// output file that contains classes.dex if it should be in the output file
-	maybeStrippedDexJarFile android.Path
-
 	// output file containing uninstrumented classes that will be instrumented by jacoco
 	jacocoReportClassesFile android.Path
 
@@ -1818,47 +1815,51 @@
 		}
 	}
 
-	if ctx.Device() && j.hasCode(ctx) &&
-		(Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) {
-		if j.shouldInstrumentStatic(ctx) {
-			j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
-				android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
-		}
-		// Dex compilation
-		var dexOutputFile android.OutputPath
-		dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName)
-		if ctx.Failed() {
-			return
-		}
-
-		// Hidden API CSV generation and dex encoding
-		dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
-			proptools.Bool(j.dexProperties.Uncompress_dex))
-
-		// merge dex jar with resources if necessary
-		if j.resourceJar != nil {
-			jars := android.Paths{dexOutputFile, j.resourceJar}
-			combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName).OutputPath
-			TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
-				false, nil, nil)
-			if *j.dexProperties.Uncompress_dex {
-				combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath
-				TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
-				dexOutputFile = combinedAlignedJar
-			} else {
-				dexOutputFile = combinedJar
+	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) {
+		if j.hasCode(ctx) {
+			if j.shouldInstrumentStatic(ctx) {
+				j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles,
+					android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags"))
 			}
+			// Dex compilation
+			var dexOutputFile android.OutputPath
+			dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName)
+			if ctx.Failed() {
+				return
+			}
+
+			// Hidden API CSV generation and dex encoding
+			dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
+				proptools.Bool(j.dexProperties.Uncompress_dex))
+
+			// merge dex jar with resources if necessary
+			if j.resourceJar != nil {
+				jars := android.Paths{dexOutputFile, j.resourceJar}
+				combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName).OutputPath
+				TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
+					false, nil, nil)
+				if *j.dexProperties.Uncompress_dex {
+					combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath
+					TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
+					dexOutputFile = combinedAlignedJar
+				} else {
+					dexOutputFile = combinedJar
+				}
+			}
+
+			j.dexJarFile = dexOutputFile
+
+			// Dexpreopting
+			j.dexpreopt(ctx, dexOutputFile)
+
+			outputFile = dexOutputFile
+		} else {
+			// There is no code to compile into a dex jar, make sure the resources are propagated
+			// to the APK if this is an app.
+			outputFile = implementationAndResourcesJar
+			j.dexJarFile = j.resourceJar
 		}
 
-		j.dexJarFile = dexOutputFile
-
-		// Dexpreopting
-		j.dexpreopt(ctx, dexOutputFile)
-
-		j.maybeStrippedDexJarFile = dexOutputFile
-
-		outputFile = dexOutputFile
-
 		if ctx.Failed() {
 			return
 		}
@@ -3183,8 +3184,7 @@
 
 	properties DexImportProperties
 
-	dexJarFile              android.Path
-	maybeStrippedDexJarFile android.Path
+	dexJarFile android.Path
 
 	dexpreopter
 
@@ -3271,8 +3271,6 @@
 
 	j.dexpreopt(ctx, dexOutputFile)
 
-	j.maybeStrippedDexJarFile = dexOutputFile
-
 	if apexInfo.IsForPlatform() {
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
 			j.Stem()+".jar", dexOutputFile)