Skip to content

R8: emit compiler r8.json into the AAB, and bump 10.0.x pack R8 off 8.11.18 (Play scores 9.0.32, not 8.11.18) #12639

Description

@yuseok-kim-edushare

Android framework version

net10.0-android

Affected platform version

Microsoft.Android.Sdk 36.1.69

Description

This is scoped to the shrinking and optimization percentages on Play Console. The obfuscation / -dontobfuscate work (#12535, #12575 and the [r8-obfuscation] stack) is separate and untouched here.

With $(AndroidLinkTool)=r8, R8 already runs with shrinking enabled, yet Play's App Bundle Explorer shows optimization and shrinking as - and only obfuscation gets a value (from mapping.txt). Per the DEX code optimization docs, for AGP 8.10+ the percentages come from BUNDLE-METADATA/com.android.tools/r8.json. The docs also say Play falls back to mapping.txt when r8.json is absent; in our measurements that fallback produced obfuscation only, never the other two.

The SDK never produces or embeds that file:

  • R8.cs has no build-metadata output. $(AndroidR8ExtraArguments) cannot be used for it from outside the SDK: D8.WriteArg writes the whole property as one response-file line, and R8's FlagFile treats one line as one token, so --build-metadata-output <path> arrives as a single unknown option. (The flag itself is supported by 8.11.18 — this is an SDK limitation, not an R8 one.)
  • _PrepareBuildApk adds exactly one AndroidAppBundleMetaDataFile entry, com.android.tools.build.obfuscation/proguard.map. Nothing for com.android.tools/r8.json.

Measurements (production .NET MAUI app, same project, same R8 flags, AndroidPackageFormat=aab, no AGP metadata injected anywhere)

DEX compiled by r8.json in AAB version in that json Play shrinking / optimization
stock pack 8.11.18 none -
A pack 8.11.18 generated via setBuildMetadataConsumer 8.11.18 - (obfuscation 37% from mapping)
B R8 9.0.32 via AndroidR8JarPath generated by 9.0.32 9.0.32 percentages shown
111 pack 8.11.18 A's json, only version changed 9.0.32 percentages shown
112 R8 9.0.32 B's json, only version changed 8.11.18 -

111/112 keep DEX bytes and dexFiles[].checksum unchanged; only the version string differs. Diffing honest 8.11.18 vs 9.0.32 json (same input): identical stats, options, dexFiles[].checksum; 8.11 additionally has compilation.*; 9.0 has no key 8.11 lacks.

Together that isolates the gate to the version string in r8.json. Two points only: 8.11.18 is rejected, 9.0.32 is accepted. The cutoff between them was not probed (it could be 8.12, 9.0.0, or something else). There is no honest way for pack 8.11.18 to produce a version Play will score.

Ask — two separable changes

  1. Generate and embed r8.json (backportable without changing the jar): an R8 task parameter that writes --build-metadata-output and the path as two response-file lines, plus one AndroidAppBundleMetaDataFile entry for com.android.tools/r8.json next to the existing proguard.map one. main already pins 9.4.17 and the net11 line (release/11.0.1xx-preview6) already pins 9.1.31; (1) is likely sufficient there. We uploaded and scored 9.0.32, and later the same production app compiled with main's R8 9.4.17 (src/r8 fat jar) — Play still filled optimization, obfuscation, and shrinking.
  2. Bump src/r8/build.gradle on release/10.0.1xx (the live net10.0-android pack line; tools jar is 8.11.18 today) to a compiler that emits a version Play accepts. 9.0.32 is the version we first uploaded and Play scored; 9.4.17 is the main pin and also scored. Change (1) alone still emits "version": "8.11.18", which Play does not score. Rewriting version in json is not an SDK solution.

Follow-up, not required to get Play to read the file: the [r8-obfuscation] PRs (#12575, #12628#12634) address -dontobfuscate / JNI renaming, not this. _CalculateProguardConfigurationFiles still passes tools/proguard-android.txt (line 16: -dontoptimize). The SDK does not currently ship proguard-android-optimize.txt. Switching that default would let compiler r8.json report optimizations enabled; it is independent of emit+embed and of the obfuscation stack.

Out of scope: -dontobfuscate / JNI remapping, shrinkResources, fabricating androidGradlePluginVersion, running Gradle in the SDK.

Steps to Reproduce

  1. Release net10.0-android, AndroidLinkTool=r8, AndroidCreateProguardMappingFile=true, AndroidPackageFormat=aab, dotnet publish.
  2. unzip -l app.aab | grep BUNDLE-METADATA → only proguard.map.
  3. Upload → App Bundle Explorer → shrinking/optimization -.
  4. Set AndroidR8JarPath to an R8 9.0.32 jar, produce r8.json via setBuildMetadataConsumer (or CLI --build-metadata-output on its own line), add it via AndroidAppBundleMetaDataFile Include="com.android.tools/r8.json:<path>", publish, upload.
  5. Percentages appear. The same DEX with json version 8.11.18 (honest pack output, or 112 in the table) shows - again.

Did you find any workaround?

the csproj targets in step 4 — an external 9.0.32 jar plus an out-of-band json producer. Apps should not have to carry that.

Relevant log output

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: App+Library BuildIssues when building Library projects or Application projects.needs-triageIssues that need to be assigned.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions