feat(android-distribution): Add APK binary identifier extraction#4713
feat(android-distribution): Add APK binary identifier extraction#4713runningcode wants to merge 2 commits intomainfrom
Conversation
|
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 85d7417 | 347.21 ms | 394.35 ms | 47.15 ms |
| 674d437 | 355.28 ms | 504.18 ms | 148.90 ms |
| 7314dbe | 437.83 ms | 505.64 ms | 67.81 ms |
| 3699cd5 | 423.60 ms | 495.52 ms | 71.92 ms |
| 17a0955 | 372.53 ms | 446.70 ms | 74.17 ms |
| ee747ae | 382.73 ms | 435.41 ms | 52.68 ms |
| ee747ae | 405.43 ms | 485.70 ms | 80.28 ms |
| b750b96 | 421.25 ms | 444.09 ms | 22.84 ms |
| ee747ae | 357.79 ms | 421.84 ms | 64.05 ms |
| ee747ae | 386.94 ms | 431.43 ms | 44.49 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 85d7417 | 1.58 MiB | 2.10 MiB | 533.44 KiB |
| 674d437 | 1.58 MiB | 2.10 MiB | 530.94 KiB |
| 7314dbe | 1.58 MiB | 2.10 MiB | 533.45 KiB |
| 3699cd5 | 1.58 MiB | 2.10 MiB | 533.45 KiB |
| 17a0955 | 1.58 MiB | 2.10 MiB | 533.20 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
| b750b96 | 1.58 MiB | 2.10 MiB | 533.20 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
c1d435c to
b68cb00
Compare
This PR adds APK signing digest extraction functionality for unique build identification, similar to Emerge Tools' approach. - Add `BinaryIdentifier.kt` with complete APK parsing implementation - Extract SHA-256/SHA-512 digests from APK signing blocks (V2/V3 signatures) - Update `DistributionInternal.kt` to use binary identifier extraction - Follow Android APK signing format specification - Reads APK file directly using RandomAccessFile - Parses ZIP structure to locate APK Signing Block - Extracts first available digest from V2 or V3 signature schemes - Returns Base64-encoded digest as stable build identifier - Gracefully handles failures (returns null if extraction fails) - Zero external dependencies (uses Android's built-in Base64) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
44cc219 to
33311a1
Compare
| while (fd.filePointer < endOfPairs) { | ||
| val id = readLittleEndianU32(fd) | ||
| val size = readLittleEndianU32(fd) | ||
| val endOfBlock = fd.filePointer + size |
There was a problem hiding this comment.
Bug: APK Signing Block Parsing Error
The parsing of APK signing block ID-value pairs is incorrect. The code expects a 4-byte ID followed by a 4-byte size, but the specification dictates an 8-byte length field before the 4-byte ID. This misinterprets the block structure, preventing correct binary identifier extraction.
There was a problem hiding this comment.
This is just a copy paste from before. What do you think of this comment @chromy ?
There was a problem hiding this comment.
Cursor is correct, this happens to work by luck currently (here and in emerge-android) all the more reason to ditch this and use the Sentry UUID.
| * @return Base64-encoded digest string if found, null otherwise | ||
| */ | ||
| internal fun getBinaryIdentifier(context: Context): String? { | ||
| return try { |
There was a problem hiding this comment.
@chromy Claude added this try catch here. I think it makes sense to keep it here in case there are weird errors reading the apk indentifier at sentry scale. WDYT?
| while (fd.filePointer < endOfPairs) { | ||
| val id = readLittleEndianU32(fd) | ||
| val size = readLittleEndianU32(fd) | ||
| val endOfBlock = fd.filePointer + size |
There was a problem hiding this comment.
This is just a copy paste from before. What do you think of this comment @chromy ?
This PR adds APK signing digest extraction functionality for unique build identification, copy pasted from Emerge Tools.
Originally authored by @chromy
#skip-changelog (We’ll add the changelog once the distribution functionality is complete.