Merge "Revert "Use R8 for resource shrinking"" into main

This commit is contained in:
Michael Stokes 2023-11-03 12:12:40 +00:00 committed by Gerrit Code Review
commit 2e09e68e56
6 changed files with 124 additions and 46 deletions

View file

@ -66,6 +66,7 @@ bootstrap_go_package {
"plugin.go",
"prebuilt_apis.go",
"proto.go",
"resourceshrinker.go",
"robolectric.go",
"rro.go",
"sdk.go",
@ -105,6 +106,7 @@ bootstrap_go_package {
"plugin_test.go",
"prebuilt_apis_test.go",
"proto_test.go",
"resourceshrinker_test.go",
"rro_test.go",
"sdk_test.go",
"sdk_library_test.go",

View file

@ -532,7 +532,7 @@ func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
a.dexpreopter.installPath = a.installPath(ctx)
a.dexpreopter.isApp = true
if a.dexProperties.Uncompress_dex == nil {
@ -545,15 +545,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
a.dexpreopter.manifestFile = a.mergedManifestFile
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
var packageResources = a.exportPackage
if ctx.ModuleName() != "framework-res" {
if Bool(a.dexProperties.Optimize.Shrink_resources) {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
aapt2Convert(ctx, protoFile, packageResources, "proto")
a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
}
var extraSrcJars android.Paths
var extraClasspathJars android.Paths
var extraCombinedJars android.Paths
@ -571,14 +563,9 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
if Bool(a.dexProperties.Optimize.Shrink_resources) {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
packageResources = binaryResources
}
}
return a.dexJarFile.PathOrNil(), packageResources
return a.dexJarFile.PathOrNil()
}
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
@ -763,6 +750,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
a.usesLibrary.freezeEnforceUsesLibraries()
@ -788,7 +776,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
dexJarFile, packageResources := a.dexBuildActions(ctx)
dexJarFile := a.dexBuildActions(ctx)
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
@ -812,7 +800,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
}
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
CreateAndSignAppPackage(ctx, packageFile, packageResources, 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)
@ -841,7 +829,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
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)

View file

@ -52,7 +52,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
})
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)
@ -71,6 +71,12 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa
Output: unsignedApk,
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)
}

View file

@ -95,8 +95,6 @@ type dexer struct {
proguardDictionary android.OptionalPath
proguardConfiguration android.OptionalPath
proguardUsageZip android.OptionalPath
resourcesInput android.OptionalPath
resourcesOutput android.OptionalPath
providesTransitiveHeaderJars
}
@ -163,7 +161,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
"$r8Template": &remoteexec.REParams{
Labels: map[string]string{"type": "compile", "compiler": "r8"},
Inputs: []string{"$implicits", "${config.R8Jar}"},
OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}"},
OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}"},
ExecStrategy: "${config.RER8ExecStrategy}",
ToolchainInputs: []string{"${config.JavaCmd}"},
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
@ -183,7 +181,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
"r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput"}, []string{"implicits"})
"r8Flags", "zipFlags", "mergeZipsFlags"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
dexParams *compileDexParams) (flags []string, deps android.Paths) {
@ -352,12 +350,6 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl
r8Flags = append(r8Flags, "-ignorewarnings")
}
if d.resourcesInput.Valid() {
r8Flags = append(r8Flags, "--resource-input", d.resourcesInput.Path().String())
r8Deps = append(r8Deps, d.resourcesInput.Path())
r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
}
return r8Flags, r8Deps
}
@ -399,8 +391,6 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
r8Deps = append(r8Deps, commonDeps...)
rule := r8
@ -419,19 +409,14 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
rule = r8RE
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
}
implicitOutputs := android.WritablePaths{
proguardDictionary,
proguardUsageZip,
proguardConfiguration}
if d.resourcesInput.Valid() {
implicitOutputs = append(implicitOutputs, resourcesOutput)
args["resourcesOutput"] = resourcesOutput.String()
}
ctx.Build(pctx, android.BuildParams{
Rule: rule,
Description: "r8",
Output: javalibJar,
ImplicitOutputs: implicitOutputs,
ImplicitOutputs: android.WritablePaths{
proguardDictionary,
proguardUsageZip,
proguardConfiguration},
Input: dexParams.classesJar,
Implicits: r8Deps,
Args: args,

44
java/resourceshrinker.go Normal file
View file

@ -0,0 +1,44 @@
// 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{
// Note that we suppress stdout to avoid successful log confirmations.
Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources >/dev/null`,
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")
}

View file

@ -0,0 +1,53 @@
// 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 (
"testing"
"android/soong/android"
)
func TestShrinkResourcesArgs(t *testing.T) {
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
).RunTestWithBp(t, `
android_app {
name: "app_shrink",
platform_apis: true,
optimize: {
shrink_resources: true,
}
}
android_app {
name: "app_no_shrink",
platform_apis: true,
optimize: {
shrink_resources: false,
}
}
`)
appShrink := result.ModuleForTests("app_shrink", "android_common")
appShrinkResources := appShrink.Rule("shrinkResources")
android.AssertStringDoesContain(t, "expected shrinker.xml in app_shrink resource shrinker flags",
appShrinkResources.Args["raw_resources"], "shrinker.xml")
appNoShrink := result.ModuleForTests("app_no_shrink", "android_common")
if appNoShrink.MaybeRule("shrinkResources").Rule != nil {
t.Errorf("unexpected shrinkResources rule for app_no_shrink")
}
}