Repository navigation
Fixes for 32-bit ARM Android (armeabi-v7a) - #6
Draft
kevinaboos wants to merge 6 commits into
Draft
kevinaboos wants to merge 6 commits into
kevinaboos wants to merge 6 commits into
Conversation
…gets Port of the `DrawVars` part of upstream commit 100b70c. On 32-bit targets (e.g., armv7 Android) the 8-byte-aligned struct ended 4 bytes past `dyn_instances`, so every draw call's `#[live]` instance fields were uploaded one f32 lane off. A const assert now keeps that gap at zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
These use the legacy syscall table, where 178 is `rt_sigqueueinfo`. `android_entry` made that call with garbage arguments on every launch on armv7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
The NDK keeps armv7 libraries under `sysroot/usr/lib/arm-linux-androideabi`, not under the clang wrapper prefix `armv7a-linux-androideabi`, so an armv7 APK/AAB never bundled a needed NDK library such as `libc++_shared.so`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
Decoding holds a few buffers of up to the cap at once (the decoder output, the RGBA buffer and an EXIF-rotated copy), and on a 32-bit target (e.g., armv7 Android) several 1 GiB ones don't fit in the address space. A large or crafted image (~1 MB on the wire) then aborted the whole app on an infallible allocation, instead of failing with `DimensionsTooLarge`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
… 32-bit `off_t` on 32-bit The 64-bit offset we pass otherwise lands where the 32-bit ABI doesn't look, so the kernel got a garbage offset on armv7. Not reached on Android today (resource paths don't exist on a device). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
3 tasks
… apps To share a private file with another app, an app gives it a `content://` URI from one of its own providers. Android 10+ apps can copy the file to MediaStore instead. On Android 8 and 9, without storage permissions, a provider is the only way. androidx's FileProvider does this for most apps, but Makepad apps don't bundle androidx. A provider must also be declared in the app's manifest, and its class compiled into the APK so the app's class loader can load it. So libraries whose Java is loaded at runtime, such as robius-share, can't ship one. MakepadFileProvider is compiled into every APK but does nothing until an app declares it in its manifest template. It serves files from the cache subdirectories named in its meta-data, read-only, to apps that were granted the URI. Like FileProvider, it refuses to run if it is exported or doesn't grant URI permissions. It resolves `..` and symlinks before checking that a file is inside a listed directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
kevinaboos
pushed a commit
to project-robius/robrix
that referenced
this pull request
Oct 26, 2026
Both branches now also carry the Android 8/9 file-sharing fix: cargo-makepad's MakepadFileProvider (kevinaboos/makepad#6) and robius-share's use of the app's provider (project-robius/robius#30). The next commit declares that provider in Robrix's manifest. An APK built with a cargo-makepad that lacks the class would crash at launch, so this pin has to land first. Only the two git revisions change. Like the previous TEMPORARY commit, replace this before merging, with `cargo update -p robius-location -p makepad-widgets` once those PRs merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes for running on 32-bit ARM Android (
armv7, ABIarmeabi-v7a), so Robrix can ship an APK for devices with a 32-bit Android system. Many of those devices run Android 8 or 9, so the last commit adds a file provider that Robrix needs to share attachments there. Each change is a separate commit.Fixes
dyn_instanceson 32-bit targets. This ports theDrawVarspart of upstream commit 100b70c, so upstreamdevalready has it.dyn_instances.#[live]instance fields (rect_pos,rect_size, colors, glyph data, ...) by one f32 lane, so the whole UI would draw wrong on armv7.constassert now keeps that gap at zero. Without the padding it fails to compile for armv7 and passes for aarch64.gettidsyscall number on 32-bit ARM and x86.rt_sigqueueinfo.android_entrymade that call with garbage arguments on every launch on armv7.sysroot/usr/lib/arm-linux-androideabi, not under the clang wrapper prefixarmv7a-linux-androideabi.libc++_shared.so. That would crash at load time as soon as any dependency used C++. Nothing in Robrix's tree does today.DimensionsTooLarge.mmap64on Android and glibc. Their plainmmaptakes a 32-bitoff_ton 32-bit targets, so the 64-bit offset we pass landed where the ABI doesn't look. This isn't reached on Android today: resource paths are build-host paths, so the file open fails first.MakepadFileProvider, a read-only file provider that apps can declare.content://URI from one of its own providers. Makepad apps don't bundle androidx'sFileProvider. A provider class must be compiled into the APK, so robius-share, whose Java is loaded at runtime, can't ship one either.classes.dex, but does nothing unless the app'sAndroidManifest.xml.templatedeclares it. The meta-datadev.makepad.android.MakepadFileProvider.cacheDirslists the cache subdirectories it serves (the class's Javadoc shows the declaration).FileProvider, it refuses to start if it is exported or doesn't grant URI permissions. It resolves..and symlinks before checking that a file is inside a listed directory.Testing
image_cachetests pass on the host, including the new one, and its unit tests type-check for armv7.cargo checkon armv7, aarch64 and the host, plus thedraw_listtest with the updatedDrawVarsliteral.mmap64link works on 32-bit glibc. They don't reproduce the bug itself: the old declaration happened to work on i686, and only goes wrong on armv7's calling convention.cargo checkforarmv7-linux-androideabiandaarch64-linux-android.Cargo.lockpointing at this branch, builds and links the armv7 and arm64 APKs with the real NDK. That also covers javac, d8 and aapt for the provider.MakepadFileProvider:It compiles cleanly with cargo-makepad's javac flags against the API 28 and API 33 stubs.
Robolectric tests on the Android 8.0 and 8.1 runtimes cover it, together with robius-share. They check:
.., encoded/, symlinks and sibling directories, which all stay refused;They fail on deliberately broken variants. The tests live outside the repo.
Notes
Cargo.locktemporarily points at this branch's head) and Support 32-bit ARM Android (armeabi-v7a), and share files on Android 8 and 9 project-robius/robius#30 (the robius side).DrawVars, are ported onto upstreamdevin theandroid_armv7_fixesbranch, for an upstream PR.Cargo.lock, so they get fixes 3 and 6 through that pin. Robrix's manifest declares the provider, so a cargo-makepad without fix 6 would build a Robrix APK that crashes at launch.glEsVersion 0x00020000, while the Android EGL code needs ES3.🤖 Generated with Claude Code
https://claude.ai/code/session_01Va5dxPCRyW8YN5b1Yt1Awy