The plugin's on-device proof (Mob.Plugin.SelfTest), run by
mix mob.selftest and mob_ci for every activated plugin.
One native round trip, no UI: location_get_once/0, then wait for what
the native side sends back to the caller.
- A fix (
{:location, %{lat: _, lon: _}}) or{:location, :error, :unavailable}pass: either proves the NIF is linked, the Kotlin bridge / Objective-C delegate is registered and the delivery path (thenativeDeliver*thunks / the delegate) is wired. A fix is a feature, not the proof. {:error, :bridge_not_registered}from the NIF (Android: the bootstrap never calledMobLocationBridge.register(), or a method-ID lookup failed) and{:location, :error, :no_activity}(the bootstrap never handed the bridge an Activity) are failures: the plugin can never answer in that host.:permission_deniedis{:skip, :needs_user}: the runner pre-grants location on emulators and simulators, so that is a device whose user has not answered.- No answer within 8 s is a skip: Android leaves a request pending with Play services disabled or the location app-op denied (MOB-403); on iOS an undecided permission prompt (which this call raises on a physical iPhone, and leaves for the user) waits for the user.
The host stub's nif_not_loaded is a failure. The test calls
location_stop/0 afterwards only on iOS, where a failed one-shot request
leaves the shared manager updating; on Android a pending request is not
cancellable and location_stop/0 would remove the host app's own
subscription instead.