Skip to content

fix(android): exclude x86_64 ABI from production AAB to resolve Play 16 KB warning#30590

Merged
andrepimenta merged 1 commit into
mainfrom
fix/android-exclude-x86_64-release-aab
May 25, 2026
Merged

fix(android): exclude x86_64 ABI from production AAB to resolve Play 16 KB warning#30590
andrepimenta merged 1 commit into
mainfrom
fix/android-exclude-x86_64-release-aab

Conversation

@andrepimenta

@andrepimenta andrepimenta commented May 25, 2026

Copy link
Copy Markdown
Member

Description

Google Play flagged two prebuilt .so files in our production AAB as non-compliant with Android's 16 KB page-size requirement, both in the x86_64 ABI:

  • base/lib/x86_64/libconceal.so — from react-native-keychain via com.facebook.conceal:1.1.3 (last released in 2016, archived upstream).
  • base/lib/x86_64/libsecp256k1.so — from react-native-fast-crypto, shipped as an IMPORTED prebuilt in its CMake config (not rebuilt from source).

Neither library can be realistically rebuilt with 16 KB alignment:

  • Facebook Conceal has been unmaintained since 2018; there is no source-of-truth fork with 16 KB alignment.
  • react-native-fast-crypto consumes libsecp256k1.so as a prebuilt binary; the existing yarn patch already adds -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON for the bridge code we compile, but it does not regenerate the imported libsecp256k1.so files.

x86_64 is only ever used by Chromebook ARC++/ARCVM and emulators — no real phone ships with an x86_64 CPU. Dropping the x86_64 ABI from production AABs silences the Play warning without affecting users.

What this PR does

Two changes that need to land together:

  1. android/gradle.properties.release — remove x86_64 from reactNativeArchitectures so React Native's own native libs (Hermes, RN core) aren't built for that ABI in the production AAB.

  2. android/app/build.gradle — add ndk.abiFilters(*reactNativeArchitectures()) inside defaultConfig. Without this, AGP packages every ABI shipped in dependency AARs regardless of reactNativeArchitectures, which is what put the x86_64 libconceal.so and libsecp256k1.so into the AAB in the first place.

A small refactor of the reactNativeArchitectures() helper to return a List (via .toList()) makes the Groovy spread *reactNativeArchitectures() into abiFilters(String...) robust across AGP/Groovy versions.

What this PR does NOT change

  • android/gradle.properties (default) — local dev still gets x86_64 emulator support.
  • android/gradle.properties.github (CI E2E, x86_64 only) — the new abiFilters resolves to ["x86_64"] in that context, so emulator tests continue to work.
  • android/gradle.properties.github.dual-versions (armeabi-v7a,arm64-v8a) — already excludes x86_64.
  • scripts/build.sh -PreactNativeArchitectures=... CLI overrides — still respected by the helper.

Follow-up work (out of scope)

The same .so files still ship for arm64-v8a with 4 KB alignment. If/when Play extends the warning to arm64, or enforces the runtime 16 KB device requirement more aggressively on Android 15+ devices in 16 KB mode, these will need structural fixes:

  • Replace react-native-fast-crypto with react-native-quick-crypto@1.x (we only consume scrypt).
  • Drop the Conceal dependency from react-native-keychain (yarn patch or upgrade to v10) — safe because minSdk = 24 means the Conceal cipher path is never selected at runtime.

Changelog

CHANGELOG entry: null

Related issues

Fixes: Google Play 16 KB page-size warning for base/lib/x86_64/libconceal.so and base/lib/x86_64/libsecp256k1.so.

Manual testing steps

Feature: Production AAB no longer contains x86_64 ABI

  Scenario: A production release build is generated
    Given a clean checkout of this branch
    When the production AAB is built via the standard release workflow
      (the same one that does `cp android/gradle.properties.release android/gradle.properties`
       before `./gradlew bundleProdRelease`)
    Then `unzip -l app-prod-release.aab | grep '/lib/'` shows only
      `lib/arm64-v8a/`, `lib/armeabi-v7a/`, and `lib/x86/` entries
    And no `lib/x86_64/` entries appear in the output
    And no `libconceal.so` or `libsecp256k1.so` files appear under any
      `lib/x86_64/` path

  Scenario: Local dev on x86_64 emulator still works
    Given a developer running `yarn android` on an Intel Mac with an x86_64 emulator
    When the debug variant is built using the default `android/gradle.properties`
    Then x86_64 native libs are still produced and the app installs and runs

  Scenario: CI E2E on x86_64 emulator still works
    Given CI overlays `android/gradle.properties.github` (reactNativeArchitectures=x86_64)
    When `./gradlew assembleProdDebug` runs
    Then the resulting APK contains a `lib/x86_64/` directory and Detox tests pass

Screenshots/Recordings

Before

Play Console flagged:

  • base/lib/x86_64/libconceal.so
  • base/lib/x86_64/libsecp256k1.so

After

Production AAB contains no lib/x86_64/ directory — both warnings cleared.

Pre-merge author checklist

  • I've followed MetaMask Contributor Docs and MetaMask Mobile Coding Standards.
  • I've completed the PR template to the best of my ability
  • I've included tests if applicable — N/A (build-config change; verification is via the unzip -l check on the produced AAB)
  • I've documented my code using JSDoc format if applicable — N/A
  • I've applied the right labels on the PR — team-mobile-platform

Performance checks (if applicable)

  • I've tested on Android — verified locally that the abiFilters change does not break the gradle.properties.github (x86_64-only) path used by CI E2E.
  • I've tested with a power user scenario — N/A (no JS behavior change)
  • I've instrumented key operations with Sentry traces — N/A

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Made with Cursor


Note

Low Risk
Build-time ABI and packaging configuration only; no runtime app logic, auth, or data-path changes, with emulator/CI paths still driven by their gradle overlays.

Overview
Production Play Store builds stop shipping x86_64 native libraries so Google Play’s 16 KB page-size warnings go away for prebuilt libconceal.so and libsecp256k1.so that only appeared under lib/x86_64/.

android/gradle.properties.release drops x86_64 from reactNativeArchitectures (now armeabi-v7a, arm64-v8a, x86). android/app/build.gradle adds defaultConfig.ndk.abiFilters(*reactNativeArchitectures()) so AGP does not still package every ABI from third-party AARs when RN’s arch list is narrower. The reactNativeArchitectures() helper now returns a Groovy List via .toList() so the spread into abiFilters is reliable.

Default and CI gradle property files are unchanged in this diff: local debug can still target x86_64 emulators, and CI E2E overlays that still set x86_64 only continue to filter to that ABI.

Reviewed by Cursor Bugbot for commit 40dd023. Bugbot is set up for automated code reviews on this repo. Configure here.

Google Play flagged base/lib/x86_64/libconceal.so (from
react-native-keychain -> com.facebook.conceal:1.1.3) and
base/lib/x86_64/libsecp256k1.so (from react-native-fast-crypto) as not
compliant with Android's 16 KB page-size requirement. Both ship as
prebuilt 4 KB-aligned binaries inside their AARs and cannot be
realistically rebuilt: Conceal is unmaintained since 2018, and
react-native-fast-crypto consumes libsecp256k1.so as an IMPORTED
prebuilt rather than building it from source.

x86_64 is only ever used by Chromebook ARC++/ARCVM and emulators; no
real phone runs x86_64. Dropping the x86_64 ABI from production AABs
silences the Play warning without affecting users.

Two changes are needed together:

1. android/gradle.properties.release: remove x86_64 from
   reactNativeArchitectures so React Native's own native libs aren't
   built for that ABI.

2. android/app/build.gradle: add ndk.abiFilters mirroring the
   reactNativeArchitectures list. Without this, AGP packages every ABI
   shipped in dependency AARs regardless of reactNativeArchitectures,
   which is what put x86_64 libconceal.so and libsecp256k1.so into the
   AAB in the first place.

Local dev (android/gradle.properties), CI E2E
(android/gradle.properties.github) and dual-version builds are
unchanged - x86_64 emulator workflows continue to work because the
abiFilters list is derived dynamically from reactNativeArchitectures.

Follow-up work tracked separately: the same .so files still ship for
arm64-v8a with 4 KB alignment. Structural fixes (replace
react-native-fast-crypto with quick-crypto scrypt, drop the Conceal
dependency in react-native-keychain since minSdk=24 means it is dead
code) will close that gap.

Co-authored-by: Cursor <cursoragent@cursor.com>
@metamaskbotv2 metamaskbotv2 Bot added the team-mobile-platform Mobile Platform team label May 25, 2026
@andrepimenta andrepimenta marked this pull request as ready for review May 25, 2026 10:23
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 97%
click to see 🤖 AI reasoning details

E2E Test Selection:
The two changed files are Android build configuration files only:

  1. android/app/build.gradle: Adds ndk { abiFilters } to restrict packaged native .so files to the architectures defined in reactNativeArchitectures(), and fixes the function to return a proper list. This is a build-time packaging change with no effect on app logic or behavior.

  2. android/gradle.properties.release: Removes x86_64 from the release build architecture list to fix Play Store 16KB page-size alignment warnings from third-party native libraries (libconceal.so from react-native-keychain and libsecp256k1.so from react-native-fast-crypto). The comment explicitly notes that E2E tests use x86_64 only, which is unaffected by this change.

These changes:

  • Only affect the release APK/AAB packaging process
  • Do not change any JavaScript, TypeScript, or React Native app code
  • Do not affect E2E test builds (which use x86_64 emulators, unchanged)
  • Do not modify any UI components, controllers, navigation, or user flows
  • Have zero impact on app performance or functionality
  • Are purely a Play Store submission compliance fix

No E2E tests need to run for these changes, and no performance tests are warranted.

Performance Test Selection:
These are Android build configuration changes affecting only native library packaging for release builds. There is no impact on app runtime performance, UI rendering, data loading, or any user-facing functionality. No performance tests are needed.

View GitHub Actions results

@andrepimenta

Copy link
Copy Markdown
Member Author

Follow-up tracking issues for the structural arm64-v8a fixes called out in this PR:

Once both land, the same .so files will no longer ship for arm64-v8a either, and we can re-enable x86_64 if there's any reason to.

@sonarqubecloud

Copy link
Copy Markdown

@andrepimenta andrepimenta added this pull request to the merge queue May 25, 2026
Merged via the queue into main with commit 4feb508 May 25, 2026
160 of 184 checks passed
@andrepimenta andrepimenta deleted the fix/android-exclude-x86_64-release-aab branch May 25, 2026 13:42
@github-actions github-actions Bot locked and limited conversation to collaborators May 25, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.80.0 Issue or pull request that will be included in release 7.80.0 label May 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.80.0 Issue or pull request that will be included in release 7.80.0 size-S team-mobile-platform Mobile Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants