Image prep downscaled every photo to 448 px and force-compressed to a
45 KB byte budget, so a typical camera photo landed ~40 KB — below
TransportConfig.wifiBulkMinPayloadBytes (64 KiB). WifiBulkPolicy.shouldOffer
requires payloadBytes > 64 KiB, so the Wi-Fi bulk (AWDL) data plane never
triggered in production even when it worked on-device: real photos always
fell back to BLE fragmentation.
Raise the prep budget so genuinely detailed photos land well above 64 KiB
while staying under the 512 KiB FileTransferLimits.maxImageBytes hard cap:
- defaultMaxDimension 448 -> 1024 px
- compressionQuality 0.82 -> 0.85
- targetImageBytes 45 KB -> 200 KB (a ceiling, not a target to hit)
Measured on a representative photo-like image: ~40 KB before -> ~190 KB
after, crossing the 64 KiB offer threshold while remaining ~2.6x under the
hard cap.
Because the raised dimension makes near-incompressible inputs (e.g. full-
frame noise) able to exceed maxImageBytes at the quality floor, prep now
downscales-and-retries until the payload fits the hard cap, so a send can
never fail with imageTooLarge on pathological input (it couldn't at 448 px).
Also de-dupes the previously copy-pasted per-platform encodeJPEG into one
shared helper.
Residual limitation: prep is not recipient-capability-aware. Images are
prepared at this fidelity regardless of whether the recipient supports
Wi-Fi bulk, so BLE-only peers and public broadcasts now carry ~190 KB
images too (still within the existing 512 KiB image cap). Making prep
choose fidelity per-recipient would need capability plumbing into the prep
pipeline and doesn't help public broadcasts, so it's deferred.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>