MOB-15: torch / flashlight support in core (Mob.Torch) - #61
Merged
Conversation
New Mob.Torch (on/1, off/1, set/2) toggles the rear-camera torch with no camera session and no permission, so it's a lightweight core capability alongside Mob.Haptic rather than part of mob_camera. - lib/mob/torch.ex — on/off API; pure state_atom/1 mapping (host-testable) - src/mob_nif.erl — torch/1 NIF declaration + stub - ios/mob_nif.m — nif_torch: AVCaptureDevice torchMode, hasTorch guard, setTorchModeOnWithLevel: at max; no-op without a torch - android/jni/mob_nif.zig — nif_torch -> MobBridge.torch(String) via the cached-method seam (Kotlin half is the paired mob_new change) - test/mob/torch_test.exs — state_atom mapping + boolean guard - decisions/2026-07-04-torch.md — core-vs-plugin + on/off-only rationale - guides/mobile_surface_matrix.md — Torch row On/off only for v1 (iOS supports brightness levels, Android setTorchMode is binary — level is a follow-up). Device verification pending (no torch on the simulator). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Both platforms physically lit the rear flash on and off — Android via :mob_nif.torch/1 over dist, iOS via an on-device Mob.Torch.set/2 button. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
GenericJam added a commit
that referenced
this pull request
Jul 5, 2026
Ships MOB-15 (#61): Mob.Torch.on/off/set toggles the rear-camera torch with no capture session and no permission. Device-verified on moto g power (2021) and iPhone SE (3rd gen). Android Kotlin bridge ships via mob_new 0.4.17+. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 freeto 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.
What
Adds
Mob.Torch— a rear-camera torch (flashlight) on/off toggle in core mob. This is themobhalf; the KotlinMobBridge.torchmethod is the paired GenericJam/mob_new PR.Linear: MOB-15 (Tier-2 hardware gap from the capability audit).
Design decisions (flagging for review — see
decisions/2026-07-04-torch.md)mob_camera. Both platforms toggle the torch without a capture session and without the camera permission (iOSAVCaptureDevice.lockForConfiguration+torchMode; AndroidCameraManager.setTorchMode). So it has no camera-plugin dependency and belongs with the other lightweight permission-free outputs likeMob.Haptic. Easy to move intomob_camerainstead if you'd rather — say the word.setTorchModeOnWithLevel:) but AndroidsetTorchModeis binary (per-torch strength is API 33+ only). A cross-platformlevel:option would be honored on one side and clamped on the other, so it's deferred to keep the contract honest. v1 drives iOS at max level.Mob.Haptic.trigger/2— returns the socket unchanged; a device with no flash unit (tablets, the simulator) is a no-op, not an error (both native sides guard on hardware presence).Layers
lib/mob/torch.ex—on/1,off/1,set/2; purestate_atom/1mapping extracted for host-testing (the MOB-6 pattern).src/mob_nif.erl—torch/1NIF declaration + stub.ios/mob_nif.m—nif_torch+ array entry.android/jni/mob_nif.zig—nif_torch→MobBridge.torch(String)via the cached-method seam (field + export +cacheRequired+ NIF table entry).test/mob/torch_test.exs,decisions/2026-07-04-torch.md, and a Torch row inguides/mobile_surface_matrix.md.Tests / checks
972 pass (3 new).
mix format,mix credo --strict,mix erlfmt --check src/,xcrun clang-format, andzig fmt --checkall clean.Merge coupling & verification
MobBridge.torch, and the zigCallStaticVoidMethodneeds the method present). Same ordering as MOB-6.🤖 Generated with Claude Code