Add soong support for resource shrinking
This adds a new flag to the optimize section to allow invoking the resource shrinker
Bug: 246217952
Test: m
Change-Id: I2e7851af1189db2a6adf6f9f9f444a1d7f3a8d60
diff --git a/java/Android.bp b/java/Android.bp
index 9df4ab4..8510e04 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -64,6 +64,7 @@
"plugin.go",
"prebuilt_apis.go",
"proto.go",
+ "resourceshrinker.go",
"robolectric.go",
"rro.go",
"sdk.go",
diff --git a/java/aapt2.go b/java/aapt2.go
index 5346ddf..7845a0b 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -256,17 +256,21 @@
var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
blueprint.RuleParams{
- Command: `${config.Aapt2Cmd} convert --output-format proto $in -o $out`,
+ Command: `${config.Aapt2Cmd} convert --output-format $format $in -o $out`,
CommandDeps: []string{"${config.Aapt2Cmd}"},
- })
+ }, "format",
+)
// Converts xml files and resource tables (resources.arsc) in the given jar/apk file to a proto
// format. The proto definition is available at frameworks/base/tools/aapt2/Resources.proto.
-func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
+func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path, format string) {
ctx.Build(pctx, android.BuildParams{
Rule: aapt2ConvertRule,
Input: in,
Output: out,
- Description: "convert to proto",
+ Description: "convert to " + format,
+ Args: map[string]string{
+ "format": format,
+ },
})
}
diff --git a/java/app.go b/java/app.go
index bccd37f..9f6b7d8 100755
--- a/java/app.go
+++ b/java/app.go
@@ -667,10 +667,9 @@
if lineage := String(a.overridableAppProperties.Lineage); lineage != "" {
lineageFile = android.PathForModuleSrc(ctx, lineage)
}
-
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
+ CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources))
a.outputFile = packageFile
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
@@ -699,7 +698,7 @@
if v4SigningRequested {
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
}
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
if v4SigningRequested {
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
diff --git a/java/app_builder.go b/java/app_builder.go
index 18a9751..d20a6bf 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -52,7 +52,7 @@
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string, shrinkResources bool) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -65,7 +65,6 @@
if jniJarFile != nil {
inputs = append(inputs, jniJarFile)
}
-
ctx.Build(pctx, android.BuildParams{
Rule: combineApk,
Inputs: inputs,
@@ -73,6 +72,11 @@
Implicits: deps,
})
+ if shrinkResources {
+ shrunkenApk := android.PathForModuleOut(ctx, "resource-shrunken", unsignedApk.Base())
+ ShrinkResources(ctx, unsignedApk, shrunkenApk)
+ unsignedApk = shrunkenApk
+ }
SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
}
@@ -84,7 +88,6 @@
certificateArgs = append(certificateArgs, c.Pem.String(), c.Key.String())
deps = append(deps, c.Pem, c.Key)
}
-
outputFiles := android.WritablePaths{signedApk}
var flags []string
if v4SignatureFile != nil {
@@ -182,7 +185,7 @@
packageFile, jniJarFile, dexJarFile android.Path) {
protoResJarFile := android.PathForModuleOut(ctx, "package-res.pb.apk")
- aapt2Convert(ctx, protoResJarFile, packageFile)
+ aapt2Convert(ctx, protoResJarFile, packageFile, "proto")
var zips android.Paths
diff --git a/java/config/config.go b/java/config/config.go
index b026d73..5cc4e51 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -165,6 +165,7 @@
pctx.HostBinToolVariable("ApiCheckCmd", "apicheck")
pctx.HostBinToolVariable("D8Cmd", "d8")
pctx.HostBinToolVariable("R8Cmd", "r8")
+ pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
pctx.VariableFunc("TurbineJar", func(ctx android.PackageVarContext) string {
diff --git a/java/dex.go b/java/dex.go
index a44d792..f5969a5 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -63,6 +63,8 @@
// classes referenced by the app manifest. Defaults to false.
No_aapt_flags *bool
+ Shrink_resources *bool
+
// Flags to pass to proguard.
Proguard_flags []string
diff --git a/java/resourceshrinker.go b/java/resourceshrinker.go
new file mode 100644
index 0000000..6d59601
--- /dev/null
+++ b/java/resourceshrinker.go
@@ -0,0 +1,43 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+)
+
+var shrinkResources = pctx.AndroidStaticRule("shrinkResources",
+ blueprint.RuleParams{
+ Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources`,
+ CommandDeps: []string{"${config.ResourceShrinkerCmd}"},
+ }, "raw_resources")
+
+func ShrinkResources(ctx android.ModuleContext, apk android.Path, outputFile android.WritablePath) {
+ protoFile := android.PathForModuleOut(ctx, apk.Base()+".proto.apk")
+ aapt2Convert(ctx, protoFile, apk, "proto")
+ strictModeFile := android.PathForSource(ctx, "prebuilts/cmdline-tools/shrinker.xml")
+ protoOut := android.PathForModuleOut(ctx, apk.Base()+".proto.out.apk")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: shrinkResources,
+ Input: protoFile,
+ Output: protoOut,
+ Args: map[string]string{
+ "raw_resources": strictModeFile.String(),
+ },
+ })
+ aapt2Convert(ctx, outputFile, protoOut, "binary")
+}