From c3e54869e434d3d8514fef075443a37dc8b73a46 Mon Sep 17 00:00:00 2001 From: Adam Legg Date: Sat, 23 May 2026 20:53:19 -0400 Subject: [PATCH 1/2] feat(iap): add plugin native source support to Android build templates Changes: - AndroidManifest.xml.eex: add com.android.vending.BILLING permission for Play Billing (used by mob_iap and any other IAP plugin) - build.zig.eex: add -Dproject_plugin_sources option that accepts comma-separated name:path pairs, allowing mob_dev to auto-discover and compile plugin C sources from deps' priv/native/android/jni/ Refs: https://github.com/GenericJam/mob/pull/27 --- .../app/src/main/AndroidManifest.xml.eex | 3 ++ .../android/app/src/main/jni/build.zig.eex | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex index 0cbdbfa..95e8d3b 100644 --- a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex +++ b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex @@ -54,6 +54,9 @@ + + + .so. + // Plugin Kotlin files are handled separately by Gradle (copied into + // the project's java tree by mob_dev). + if (project_plugin_sources.len > 0) { + var plug_it = std.mem.splitScalar(u8, project_plugin_sources, ','); + while (plug_it.next()) |pair| { + if (pair.len == 0) continue; + var colon_it = std.mem.splitScalar(u8, pair, ':'); + const name = colon_it.next() orelse continue; + const path = colon_it.next() orelse continue; + const obj = addCObject(b, .{ + .name = name, + .source = path, + .target = target, + .optimize = optimize, + .c_flags = c_flags, + .otp_dir = otp_dir, + .erts_vsn = erts_vsn, + .mob_dir = mob_dir, + }); + const install = b.addInstallFile(obj, b.fmt("{s}/{s}.o", .{ abi, name })); + c_objects_step.dependOn(&install.step); + obj_paths.append(b.allocator, obj) catch @panic("OOM"); + } + } + // Link: zig cc -shared, mirroring CMake's prior target_link_libraries // (--gc-sections + --whole-archive bracket around the OTP/crypto static // libs + plain libcrypto.a + Android system libs). Returns the cp From 4f92e9fd96efaf8898527491c7360c6b28b3b25b Mon Sep 17 00:00:00 2001 From: Adam Legg Date: Sat, 23 May 2026 22:00:38 -0400 Subject: [PATCH 2/2] docs: explain BILLING permission tradeoff in AndroidManifest template The previous one-line comment didn't capture why the permission is declared unconditionally vs. gated on a generator flag. Expand it to document both the rationale (avoid generator complexity) and the tradeoff (Play Console may warn non-IAP apps about the unused permission) so users know how to opt out. Template-only change; no behavior shift. Co-Authored-By: Claude Opus 4.7 --- .../android/app/src/main/AndroidManifest.xml.eex | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex index 95e8d3b..b84c4ee 100644 --- a/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex +++ b/priv/templates/mob.new/android/app/src/main/AndroidManifest.xml.eex @@ -54,7 +54,19 @@ - +