From b014f0787edaa598e4d7186fc174c28b0091ed3a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 26 Feb 2021 14:54:36 -0800 Subject: [PATCH] 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 --- java/androidmk.go | 2 +- java/app.go | 2 +- java/app_test.go | 45 ++++++++++++++++++++++++ java/java.go | 88 +++++++++++++++++++++++------------------------ 4 files changed, 90 insertions(+), 47 deletions(-) diff --git a/java/androidmk.go b/java/androidmk.go index 9bdb70cb9..3d3eae530 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -220,7 +220,7 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries { } 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 8287533e0..39f06d004 100755 --- a/java/app.go +++ b/java/app.go @@ -469,7 +469,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { 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 b1abe3db3..349579e97 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -685,6 +685,51 @@ func TestLibraryAssets(t *testing.T) { } } +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 78cd362d8..698c5b915 100644 --- a/java/java.go +++ b/java/java.go @@ -434,9 +434,6 @@ type Module struct { // 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 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } } - 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 @@ type DexImport struct { properties DexImportProperties - dexJarFile android.Path - maybeStrippedDexJarFile android.Path + dexJarFile android.Path dexpreopter @@ -3271,8 +3271,6 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.dexpreopt(ctx, dexOutputFile) - j.maybeStrippedDexJarFile = dexOutputFile - if apexInfo.IsForPlatform() { ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), j.Stem()+".jar", dexOutputFile)