Skip to content

Conversation

@wheregmis
Copy link
Contributor

@wheregmis wheregmis commented Oct 26, 2025

This PR introduces a comprehensive linker-based permission management for automatic update of manifest files and android native plugin building foundation for Dioxus. The implementation is inspired by Manganis's linker-based asset collection approach.

Build on top of #4932 so diff is huge for now

Two main motivation for this PR

  1. To automatically handle the manifest file and info.plist file instead of invoking, ejecting or providing custom file.
  2. Able to pass in the java file path through linker, copy and bundle them (Opening doors for android native apis development)

To break things in chain for android side of things,

Just from top level how it works is

  • We do something like this in plugins
#[cfg(target_os = "android")]
dioxus_platform_bridge::android_plugin!(
    package = "dioxus.mobile.geolocation",
    plugin = "geolocation",
    files = ["src/android/PermissionsHelper.java"]
);
  • The macro embeds metadata into the compiled binary as a linker symbol named JAVA_SOURCE... with a hash.
  • This metadata contains the Java file paths, package name, and plugin name.

From CLI

  • Finds JAVA_SOURCE... symbols in the compiled binary.
  • Deseralize the metadata to get the java files
  • Reads the files from the disk
  • Copies them to gradle project (app/src/main/java)
  • Gradle Compiles and bundle
  • Similarly we register PERMISSION symbols from those plugins which we extract on the CLI and update the manifest.

Example Geolocation crate: https://github.com/wheregmis/mobile-geolocation
Example Demo: https://github.com/wheregmis/geolocation-demo

New crates: (Please suggest the names as i am bad at naming stuff)

  • permissions: Public API that re-exports permissions-core and permissions-macro for easy integration.
  • permissions-core: Types for permission declaration and platform identifiers (Android, IOS, MacOS) (We can extend the identifiers as needed or requested)
  • permissions-macro: Procedural Macros (static_permission!) for declaring permissions via linker symbol (So cli can extract the symbols and update the manifest files automatically)
  • dx-macro-helpers: Common helpers for linker based stuff, shared by manganis and permission
  • platform-bridge: Bareminimal Cross-platform FFI utilities and plugin metadata for Android (JNI) and Darwin (objc2)
  • platform-bridge-macro: android_plugin! macro for embedding Java source file paths in binaries via linker symbols

Extend Geolocation to support other os and build the framwork on platform-bridge and cli. (This portion of the code i will generate from AI as I believe there are other good people who can build full fledge Cross Platform Location Service, and just a note that this AI generated piece of code will leave outside dioxus repo, its just to test the platform-bridge and permissions)

  • MacOS
  • IOS
  • Android
    Below Platform uses runtime based permissions so we dont need to do anything for them on dioxus repo.
    Linux (The permissions are runtime based and can be handled from standard rust crates like rfd, std::fs, so we dont need to do anything on platform bridge side)
    Windows (The permissions are runtime based and can be handled from standard rust crates like windows-rs, winapi, so we dont need to do anything on platform bridge side)
  • Web

@wheregmis
Copy link
Contributor Author

Yey, Android Permission Dialog is working.
Screenshot_1761495440

Improves code formatting in has_location_permission and check_permission functions by splitting long lines and updating function signatures for better readability. No functional changes were made.
The java_plugin macro now accepts full relative paths for Java files instead of assuming a fixed directory structure. Documentation and usage examples have been updated to reflect this change, improving flexibility and clarity for specifying file locations.
Added checks for authorization status before requesting location permissions and retrieving location data. Now only requests permission if not determined, and attempts to retrieve cached location before starting location updates, improving efficiency and user experience.
Introduces the ios_plugin! macro in mobile-core-macro for declarative iOS framework metadata embedding. Updates mobile-core to re-export the macro and refactors mobile-geolocation to use ios_plugin! instead of manual linker attributes.
wheregmis and others added 3 commits November 5, 2025 19:38
- Added #[used] attribute to linker sections in both permission and Android plugin macros to prevent the linker from optimizing away symbols, ensuring they are preserved even if unused.
- Created static references to linker sections to enhance defense-in-depth against optimization issues.
@jkelleyrtp
Copy link
Member

jkelleyrtp commented Nov 6, 2025

Going through the linker seems to be the right approach for permissions. Both build scripts and linker will require an end tool to collect the permissions, and I much prefer infrastructure-as-code approaches than the implicit build script. It's nice that not using a permission means not inserting it the Info.plist. Instead of #[used] attributes I would prefer that we make the permission a required argument to the function that requests the permission, and then we perform a volatile read, forcing the symbol to remain. This is similar to how Asset remains because its Display impl forces a volatile read.

We might need to think about Koitlin/Swift source files a bit more since cargo's cache busting system will be more reliable than the linker-based system, at least early on.

However, I'd rather not create a new symbol type for collecting permissions and instead try to reuse the one we use for assets. Though, the asset symbol format is not very flexible (see #4863), so it might require some work on our end to allow different variants as long as they're the same size. Adding a new symbol seems to require duplicating logic in the CLI which we can avoid if we stick with one symbol with different variants.


Also, FWIW, this would be at the top of the list for 0.8 features. If we could get it in 0.7, then it would be at the top of priority behind fixing bugs, that way we can ship native apis while still on 0.7

@wheregmis
Copy link
Contributor Author

@jkelleyrtp Thank you for the inputs. All the recommendation and inputs seems super valid and reasonable. After looking into #4863 I do think if we can somehow provide a appropriate way of creating different variants, and we dont need to create multiple symbols, alot of code on the CLI for extracting symbols can be alot more refined and cleaned. For kotlin/swift sources files, I also dont have super huge usecase to get into alot more depth to learn and define the fundamentals so i would definately leave these big chunks to dioxus core members. For the time being i will try to update my codes to more like an enum of LinkerSymbol which can hold either asset or permission and try to cleanup the CLI code abit so we dont go with multiple symbol type and can slip the permissions under MANGANIS symbol. And when we have a concrete plan for #4863 I can update my code for it. Also maybe we can try to slip in the permissions related stuff if possible into the 0.7 that way in with permissions, followed by build system for kotlin/swift and native apis can be added and shipped while still on 0.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants