diff --git a/android/config.go b/android/config.go index 43eeb9751..d1db87b24 100644 --- a/android/config.go +++ b/android/config.go @@ -208,6 +208,7 @@ func TestConfig(buildDir string, env map[string]string) Config { AAPTPreferredConfig: stringPtr("xhdpi"), AAPTCharacteristics: stringPtr("nosdcard"), AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"}, + UncompressPrivAppDex: boolPtr(true), }, buildDir: buildDir, diff --git a/java/app.go b/java/app.go index 8d41b570f..ad672ead4 100644 --- a/java/app.go +++ b/java/app.go @@ -188,17 +188,18 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { return true } - if ctx.Config().UnbundledBuild() { - return false - } - - // Uncompress dex in APKs of privileged apps, and modules used by privileged apps. + // Uncompress dex in APKs of privileged apps, and modules used by privileged apps + // (even for unbundled builds, they may be preinstalled as prebuilts). if ctx.Config().UncompressPrivAppDex() && (Bool(a.appProperties.Privileged) || inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules())) { return true } + if ctx.Config().UnbundledBuild() { + return false + } + // Uncompress if the dex files is preopted on /system. if !a.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, a.dexpreopter.installPath)) { return true diff --git a/java/app_test.go b/java/app_test.go index d2685107e..2bd44ad4a 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -24,6 +24,8 @@ import ( "sort" "strings" "testing" + + "github.com/google/blueprint/proptools" ) var ( @@ -1063,3 +1065,86 @@ func TestEmbedNotice(t *testing.T) { t.Errorf("mergeNotices shouldn't have run for baz") } } + +func TestUncompressDex(t *testing.T) { + testCases := []struct { + name string + bp string + + uncompressedPlatform bool + uncompressedUnbundled bool + }{ + { + name: "normal", + bp: ` + android_app { + name: "foo", + srcs: ["a.java"], + } + `, + uncompressedPlatform: true, + uncompressedUnbundled: false, + }, + { + name: "use_embedded_dex", + bp: ` + android_app { + name: "foo", + use_embedded_dex: true, + srcs: ["a.java"], + } + `, + uncompressedPlatform: true, + uncompressedUnbundled: true, + }, + { + name: "privileged", + bp: ` + android_app { + name: "foo", + privileged: true, + srcs: ["a.java"], + } + `, + uncompressedPlatform: true, + uncompressedUnbundled: true, + }, + } + + test := func(t *testing.T, bp string, want bool, unbundled bool) { + t.Helper() + + config := testConfig(nil) + if unbundled { + config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) + } + + ctx := testAppContext(config, bp, nil) + + run(t, ctx, config) + + foo := ctx.ModuleForTests("foo", "android_common") + dex := foo.Rule("r8") + uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0") + aligned := foo.MaybeRule("zipalign").Rule != nil + + if uncompressedInDexJar != want { + t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar) + } + + if aligned != want { + t.Errorf("want aligned %v, got %v", want, aligned) + } + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + t.Run("platform", func(t *testing.T) { + test(t, tt.bp, tt.uncompressedPlatform, false) + }) + t.Run("unbundled", func(t *testing.T) { + test(t, tt.bp, tt.uncompressedUnbundled, true) + }) + }) + } +}