Merge "Store dex files uncompressed and unstripped in privileged APKs"
diff --git a/android/config.go b/android/config.go
index 3b7b477..695a298 100644
--- a/android/config.go
+++ b/android/config.go
@@ -708,6 +708,22 @@
return Bool(c.productVariables.HostStaticBinaries)
}
+func (c *config) UncompressPrivAppDex() bool {
+ return Bool(c.productVariables.UncompressPrivAppDex)
+}
+
+func (c *config) ModulesLoadedByPrivilegedModules() []string {
+ return c.productVariables.ModulesLoadedByPrivilegedModules
+}
+
+func (c *config) DefaultStripDex() bool {
+ return Bool(c.productVariables.DefaultStripDex)
+}
+
+func (c *config) DisableDexPreopt(name string) bool {
+ return Bool(c.productVariables.DisableDexPreopt) || InList(name, c.productVariables.DisableDexPreoptModules)
+}
+
func (c *deviceConfig) Arches() []Arch {
var arches []Arch
for _, target := range c.config.Targets[Android] {
diff --git a/android/variable.go b/android/variable.go
index 2eb9900..f2ba89b 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -190,6 +190,12 @@
Arc *bool `json:",omitempty"`
MinimizeJavaDebugInfo *bool `json:",omitempty"`
+ UncompressPrivAppDex *bool `json:",omitempty"`
+ ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
+ DefaultStripDex *bool `json:",omitempty"`
+ DisableDexPreopt *bool `json:",omitempty"`
+ DisableDexPreoptModules []string `json:",omitempty"`
+
IntegerOverflowExcludePaths *[]string `json:",omitempty"`
EnableCFI *bool `json:",omitempty"`
diff --git a/java/app.go b/java/app.go
index 5d25dcf..d1b04c3 100644
--- a/java/app.go
+++ b/java/app.go
@@ -67,7 +67,9 @@
// list of native libraries that will be provided in or alongside the resulting jar
Jni_libs []string `android:"arch_variant"`
- EmbedJNI bool `blueprint:"mutated"`
+ AllowDexPreopt bool `blueprint:"mutated"`
+ EmbedJNI bool `blueprint:"mutated"`
+ StripDex bool `blueprint:"mutated"`
}
type AndroidApp struct {
@@ -139,6 +141,42 @@
a.generateAndroidBuildActions(ctx)
}
+// Returns whether this module should have the dex file stored uncompressed in the APK, or stripped completely. If
+// stripped, the code will still be present on the device in the dexpreopted files.
+// This is only necessary for APKs, and not jars, because APKs are signed and the dex file should not be uncompressed
+// or removed after the signature has been generated. For jars, which are not signed, the dex file is uncompressed
+// or removed at installation time in Make.
+func (a *AndroidApp) uncompressOrStripDex(ctx android.ModuleContext) (uncompress, strip bool) {
+ if ctx.Config().UnbundledBuild() {
+ return false, false
+ }
+
+ strip = ctx.Config().DefaultStripDex()
+ // TODO(ccross): don't strip dex installed on partitions that may be updated separately (like vendor)
+ // TODO(ccross): don't strip dex on modules with LOCAL_APK_LIBRARIES equivalent
+ // TODO(ccross): don't strip dex on modules that are preopted to system_other
+
+ // Uncompress dex in APKs of privileged apps, and modules used by privileged apps.
+ if ctx.Config().UncompressPrivAppDex() &&
+ (Bool(a.appProperties.Privileged) ||
+ inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules())) {
+
+ uncompress = true
+ // If the dex files is store uncompressed, don't strip it, we will reuse the uncompressed dex from the APK
+ // instead of copying it into the odex file.
+ strip = false
+ }
+
+ // If dexpreopt is disabled, don't strip the dex file
+ if !a.appProperties.AllowDexPreopt ||
+ !BoolDefault(a.deviceProperties.Dex_preopt.Enabled, true) ||
+ ctx.Config().DisableDexPreopt(ctx.ModuleName()) {
+ strip = false
+ }
+
+ return uncompress, strip
+}
+
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
linkFlags := append([]string(nil), a.extraLinkFlags...)
@@ -184,11 +222,16 @@
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, staticLibProguardFlagFiles...)
a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile)
+ a.deviceProperties.UncompressDex, a.appProperties.StripDex = a.uncompressOrStripDex(ctx)
+
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
}
+ dexJarFile := a.dexJarFile
- packageFile := android.PathForModuleOut(ctx, "package.apk")
+ if a.appProperties.StripDex {
+ dexJarFile = nil
+ }
var certificates []certificate
@@ -226,8 +269,8 @@
certificates = append([]certificate{a.certificate}, certificateDeps...)
- CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, a.outputFile, certificates)
-
+ packageFile := android.PathForModuleOut(ctx, "package.apk")
+ CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
a.outputFile = packageFile
if ctx.ModuleName() == "framework-res" {
@@ -284,6 +327,7 @@
module.Module.properties.Instrument = true
module.Module.properties.Installable = proptools.BoolPtr(true)
+ module.appProperties.AllowDexPreopt = true
module.AddProperties(
&module.Module.properties,
@@ -345,6 +389,7 @@
module.Module.properties.Instrument = true
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.EmbedJNI = true
+ module.appProperties.AllowDexPreopt = false
module.AddProperties(
&module.Module.properties,
@@ -379,6 +424,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.EmbedJNI = true
+ module.appProperties.AllowDexPreopt = false
module.AddProperties(
&module.Module.properties,
diff --git a/java/app_builder.go b/java/app_builder.go
index b9b5f43..7577444 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -87,9 +87,6 @@
certificateArgs = append(certificateArgs, c.pem.String(), c.key.String())
}
- // TODO(ccross): sometimes uncompress dex
- // TODO(ccross): sometimes strip dex
-
ctx.Build(pctx, android.BuildParams{
Rule: signapk,
Description: "signapk",
diff --git a/java/dex.go b/java/dex.go
index 625fb83..5cec325 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -26,7 +26,7 @@
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`${config.D8Cmd} --output $outDir $d8Flags $in && ` +
- `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.D8Cmd}",
@@ -34,7 +34,7 @@
"${config.MergeZipsCmd}",
},
},
- "outDir", "d8Flags")
+ "outDir", "d8Flags", "zipFlags")
var r8 = pctx.AndroidStaticRule("r8",
blueprint.RuleParams{
@@ -46,7 +46,7 @@
`-printmapping $outDict ` +
`$r8Flags && ` +
`touch "$outDict" && ` +
- `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.R8Cmd}",
@@ -54,7 +54,7 @@
"${config.MergeZipsCmd}",
},
},
- "outDir", "outDict", "r8Flags")
+ "outDir", "outDict", "r8Flags", "zipFlags")
func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
flags := j.deviceProperties.Dxflags
@@ -172,6 +172,11 @@
javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
outDir := android.PathForModuleOut(ctx, "dex")
+ zipFlags := ""
+ if j.deviceProperties.UncompressDex {
+ zipFlags = "-L 0"
+ }
+
if useR8 {
proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary")
j.proguardDictionary = proguardDictionary
@@ -184,9 +189,10 @@
Input: classesJar,
Implicits: r8Deps,
Args: map[string]string{
- "r8Flags": strings.Join(r8Flags, " "),
- "outDict": j.proguardDictionary.String(),
- "outDir": outDir.String(),
+ "r8Flags": strings.Join(r8Flags, " "),
+ "zipFlags": zipFlags,
+ "outDict": j.proguardDictionary.String(),
+ "outDir": outDir.String(),
},
})
} else {
@@ -198,8 +204,9 @@
Input: classesJar,
Implicits: d8Deps,
Args: map[string]string{
- "d8Flags": strings.Join(d8Flags, " "),
- "outDir": outDir.String(),
+ "d8Flags": strings.Join(d8Flags, " "),
+ "zipFlags": zipFlags,
+ "outDir": outDir.String(),
},
})
}
diff --git a/java/java.go b/java/java.go
index f651884..1a73133 100644
--- a/java/java.go
+++ b/java/java.go
@@ -257,6 +257,8 @@
// When targeting 1.9, override the modules to use with --system
System_modules *string
+
+ UncompressDex bool `blueprint:"mutated"`
}
// Module contains the properties and members used by all java module types