ADR-0011: 16 KB page-size support
- Status: Accepted (revised — supersedes this ADR's 2026-08-11 revision)
- Date: 2026-08-13
- Deciders: maintainers
- Related: tooling.md
Supersedes the earlier Accepted revision (2026-08-11), which realigned the 4 KB-linked
libsqlcipher.soat build time. That approach turned out not to satisfy the runtime 16 KB check on Android 17 devices.
Context
Google Play requires apps targeting Android 15+ to support 16 KB page sizes.
The original revision of this ADR patched the 4 KB-aligned
android-database-sqlcipher AAR at build time (PatchSqlcipherTask +
scripts/patch_elf_16k.py), rewriting LOAD segment p_offset/p_align so
p_offset ≡ p_vaddr (mod 16384) and p_align = 16384.
That patch passes zipalign -P 16 but does not survive Android 17's
strict loader. ElfReader::FixMinAlignFor16KiB (added in Android 17) lowers
min_align_ to 4096 when LOAD segments overlap after 16 KB page-rounding:
if (prev_load_end > page_start(phdr->p_vaddr)) { min_align_ = 4 * 1024; }
The patched libsqlcipher.so still has non-16 KB-aligned p_vaddr
(0x3abc80, 0x3d3a10), so it fails this check and the device rejects it
with program alignment (4096) cannot be smaller than system page size (16384).
A file-offset patch cannot fix this — it would require relocating every
vaddr-based structure (relinking).
Zetetic confirmed android-database-sqlcipher is end-of-life and will never
ship a 16 KB build. The official replacement sqlcipher-android has been
16 KB-aligned since 4.6.1.
Decision
Migrate to net.zetetic:sqlcipher-android (4.17.0) and delete the build-time
patch machinery:
- Replace the dependency (
android-database-sqlcipher→sqlcipher-android). - Replace
net.sqlcipher.database.SupportFactorywithnet.zetetic.database.sqlcipher.SupportOpenHelperFactory, and callSystem.loadLibrary("sqlcipher")before opening (the new library no longer auto-loads its native code). - Drop
PatchSqlcipherTask,scripts/patch_elf_16k.py, andscripts/patch_sqlcipher_aar.py.
The on-disk SQLCipher format is unchanged across 4.x, so existing encrypted databases open without a data migration.
Consequences
- The shipped
libsqlcipher.sois genuinely 16 KB-aligned and loads on 16 KB devices without any compat property. - No custom build step for native libraries; the patch scripts and Gradle task are gone.
- Verified end-to-end: fresh install on a 16 KB emulator (no alignment crash) and in-place upgrade of an existing encrypted DB on a 4 KB emulator (data preserved, same DB file).
- Encryption behavior is guarded by
SqlcipherEncryptionTest(round-trip, wrong-passphrase rejection, not-plaintext).
Alternatives considered
- Rebuilding
android-database-sqlcipherfrom source with-Wl,-z,max-page-size=16384— rejected: heavy native toolchain and upkeep, and the library is EOL. - Keeping the build-time ELF patch — rejected: fails Android 17's strict 16 KB loader (see Context).
- Licensing the Commercial Edition — rejected: migration to the open-source replacement is sufficient.