Packages
mob
0.7.1
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.2
0.6.1
0.6.0
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.11
0.5.10
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
BEAM-on-device mobile framework for Elixir
Current section
Files
Jump to
Current section
Files
android/jni/mob_beam.h
// mob_beam.h — Public API for mob's BEAM launcher and UI initialisation.
// Include this in your app's beam_jni.c stub.
#ifndef MOB_BEAM_H
#define MOB_BEAM_H
#include <jni.h>
#include <stddef.h> // size_t — ditto
#include <stdint.h> // uint8_t — for mob_deliver_vendor_usb_data
// Call from JNI_OnLoad (main thread).
// bridge_class: e.g. "com/myapp/MobBridge"
void mob_ui_cache_class(JNIEnv *env, const char *bridge_class);
// Send a tap event to the BEAM process registered for handle.
// Called from the app's Java_..._MobBridge_nativeSendTap JNI stub.
void mob_send_tap(int handle);
// Send a {:change, tag, value} event. Called from the app's
// Java_..._MobBridge_nativeSendChange* JNI stubs.
void mob_send_change_str(int handle, const char *utf8);
void mob_send_change_bool(int handle, int bool_val); // 0 = false, 1 = true
void mob_send_change_float(int handle, double value);
// Send {:focus, tag}, {:blur, tag}, {:submit, tag} events.
void mob_send_focus(int handle);
void mob_send_blur(int handle);
void mob_send_submit(int handle);
// Send {:select, tag} for pickers, menus, segmented controls.
void mob_send_select(int handle);
// Send {:compose, tag, %{text, phase}} for IME composition events on text
// fields. phase is "began" | "updating" | "committed" | "cancelled". Apps
// that observe this can implement commit-only behaviour for CJK input
// (ignore on_change while composing, replace text on :committed).
void mob_send_compose(int handle, const char *text, const char *phase);
// ── Gesture senders (Batch 4) ────────────────────────────────────────────
// Called from beam_jni.c JNI stubs when Compose's gesture detector fires.
// Per-widget opt-in — only nodes with the corresponding registered handle emit.
void mob_send_long_press(int handle);
void mob_send_double_tap(int handle);
void mob_send_swipe_left(int handle);
void mob_send_swipe_right(int handle);
void mob_send_swipe_up(int handle);
void mob_send_swipe_down(int handle);
// Direction-aware: emits {:swipe, tag, direction_atom} where direction is
// "left" | "right" | "up" | "down".
void mob_send_swipe_with_direction(int handle, const char *direction);
// ── Batch 5 Tier 1: high-frequency scroll/drag/pinch/rotate/pointer ─────
// Throttling and delta-thresholding are applied native-side BEFORE these
// fire — by the time they're called, the BEAM crossing is justified.
// Defaults (when no explicit config): scroll 33ms/1px, drag 16ms/1px,
// pinch 16ms/0.01, rotate 16ms/1°, pointer_move 33ms/4px.
void mob_set_throttle_config(int handle, int throttle_ms, int debounce_ms, double delta_threshold,
int leading, int trailing);
// Phase is "began" | "dragging" | "decelerating" | "ended"
void mob_send_scroll(int handle, double x, double y, double dx, double dy, double vx, double vy,
const char *phase);
void mob_send_drag(int handle, double x, double y, double dx, double dy, const char *phase);
void mob_send_pinch(int handle, double scale, double velocity, const char *phase);
void mob_send_rotate(int handle, double degrees, double velocity, const char *phase);
void mob_send_pointer_move(int handle, double x, double y);
// ── Batch 5 Tier 2: semantic single-fire scroll events ──
void mob_send_scroll_began(int handle);
void mob_send_scroll_ended(int handle);
void mob_send_scroll_settled(int handle);
void mob_send_top_reached(int handle);
void mob_send_scrolled_past(int handle);
// Signal a system back gesture to the BEAM screen process.
// The BEAM pops the nav stack or calls exit_app if at root.
void mob_handle_back(void);
// Call from nativeSetActivity.
void mob_init_bridge(JNIEnv *env, jobject activity);
// Call from nativeStartBeam.
// app_module: Erlang module name, e.g. "mob_demo"
void mob_start_beam(const char *app_module);
// Update the startup status shown on screen while BEAM is initialising.
// mob_set_startup_error stalls the screen with an error message (does not crash).
// Both are safe to call from any thread; no-op if MobBridge lacks the method.
void mob_set_startup_phase(const char *phase);
void mob_set_startup_error(const char *error);
// Global JVM pointer — defined in mob_beam.c, extern'd for mob_nif.c.
extern JavaVM *g_jvm;
extern jobject g_activity;
// ── Device capability delivery functions ─────────────────────────────────
// Called from beam_jni.c JNI stubs when Kotlin delivers async results.
// pid is an ErlNifPid passed as jlong through Kotlin.
void mob_deliver_atom2(jlong pid, const char *a1, const char *a2);
void mob_deliver_atom3(jlong pid, const char *a1, const char *a2, const char *a3);
void mob_deliver_motion(jlong pid, double ax, double ay, double az, double gx, double gy, double gz,
long long ts);
void mob_deliver_file_result(jlong pid, const char *event, const char *sub, const char *json_items);
void mob_deliver_camera_frame(jlong pid, const unsigned char *bytes, size_t nbytes, int width,
int height, const char *format, jlong timestamp_ms, jlong dropped);
void mob_deliver_push_token(jlong pid, const char *token);
void mob_deliver_notification(jlong pid, const char *json);
void mob_set_launch_notification(const char *json);
// Store a document ("open with") item JSON ({path,name,mime,size}) handed to us
// by MainActivity from an ACTION_VIEW / ACTION_SEND intent. Consumed via
// Mob.Files.take_opened_document/0.
void mob_set_opened_document(const char *json);
// Deliver WebView events from Java/Kotlin to the registered owner pid.
// `mob_deliver_webview_message` for postMessage payloads from JS,
// `mob_deliver_webview_blocked` for navigation attempts to disallowed URLs.
void mob_deliver_webview_message(jlong pid, const char *json);
void mob_deliver_webview_blocked(jlong pid, const char *url);
// Deliver vendor_usb (Mob.VendorUsb / USB host) events. Each builds a
// 5-tuple {:peripheral, :vendor_usb, tag, session, payload} and posts
// it to pid. devices/permission/opened carry a JSON binary, decoded
// Elixir-side by Mob.VendorUsb.normalize_message/1. session=-1 → :nil
// atom; session>=0 → integer.
void mob_deliver_vendor_usb_devices(jlong pid, const char *json_array);
void mob_deliver_vendor_usb_permission(jlong pid, int granted, const char *device_json);
void mob_deliver_vendor_usb_opened(jlong pid, int session, const char *device_json);
void mob_deliver_vendor_usb_data(jlong pid, int session, const uint8_t *bytes, size_t nbytes);
void mob_deliver_vendor_usb_write_complete(jlong pid, int session, int bytes_written);
void mob_deliver_vendor_usb_event(jlong pid, int session,
const char *tag, // "closed" | "disconnected" | "error"
const char *reason); // atom-safe ASCII or NULL
// Deliver {:alert, action_atom} to the registered :mob_screen process.
// Called from beam_jni.c when a dialog button is tapped.
void mob_deliver_alert_action(const char *action);
// Deliver {:component_event, event, payload_json} to a native view component process.
// Called from beam_jni.c when Kotlin fires a component event via the send callback.
void mob_send_component_event(int handle, const char *event, const char *payload_json);
// Deliver {:mob_device, :color_scheme_changed, :light | :dark} to the
// dispatcher pid registered via Mob.Device. Called from beam_jni.c's
// nativeNotifyColorScheme when MainActivity sees a uiMode flip.
// `scheme` must be "light" or "dark".
void mob_send_color_scheme_changed(const char *scheme);
// mob_beam.h additions for Mob.Bt
//
// Append these to the existing mob_beam.h, after the
// mob_deliver_vendor_usb_* block. Order matches the
// `pub export fn mob_deliver_bt_*` definitions in mob_nif.zig.
//
// All BT deliveries take a jlong pid (ErlNifPid round-tripped through
// Kotlin) and post a 4-tuple `{:bt|:bt_hfp|:bt_spp|:bt_hid, tag, session_or_nil, payload}`
// to that pid. Payload shape varies by event; see mob_nif.zig for details.
// ── Discovery (no-payload 2-tuples) ──────────────────────────────────────
void mob_deliver_bt_discovery_started(jlong pid);
void mob_deliver_bt_discovery_finished(jlong pid);
void mob_deliver_bt_discovery_cancelled(jlong pid);
// ── Discovery / pairing events (3-tuples, no session) ────────────────────
void mob_deliver_bt_discovered(jlong pid, const char *address, const char *name, int bonded);
void mob_deliver_bt_paired(jlong pid, const char *address, const char *name, int bonded);
void mob_deliver_bt_pair_failed(jlong pid, const char *address, const char *reason);
void mob_deliver_bt_unpaired(jlong pid, const char *address);
void mob_deliver_bt_error(jlong pid, const char *reason);
// ── Legacy JSON paired-devices envelope (compat with older mob_new templates) ──
void mob_deliver_bt_paired_devices(jlong pid, const char *json);
// ── Paired-list streaming (begin / entry / finish) ──────────────────────
// Kotlin invokes begin, then 0..N entry calls, then finish. The finish
// call emits a single `{:bt, :paired_list, list}` to the originating pid.
void mob_deliver_bt_paired_list_begin(jlong pid);
void mob_deliver_bt_paired_list_entry(jlong pid, const char *address, const char *name, int bonded);
void mob_deliver_bt_paired_list_finish(jlong pid);
// ── HFP profile (8 deliveries) ──────────────────────────────────────────
void mob_deliver_bt_hfp_connecting(jlong pid, int session, const char *address);
void mob_deliver_bt_hfp_connected(jlong pid, int session, const char *address, const char *name);
void mob_deliver_bt_hfp_connect_failed(jlong pid, const char *address, const char *reason);
void mob_deliver_bt_hfp_disconnected(jlong pid, int session, const char *reason_atom);
void mob_deliver_bt_hfp_vendor_subscribed(jlong pid, int session);
void mob_deliver_bt_hfp_vendor_at(jlong pid, int session, const char *cmd, int cmd_type,
const char *args, const char *address);
void mob_deliver_bt_hfp_sco_started(jlong pid, int session, const char *address);
void mob_deliver_bt_hfp_sco_stopped(jlong pid, int session);
void mob_deliver_bt_hfp_sco_audio(jlong pid, int session, const char *pcm, size_t len);
void mob_deliver_bt_hfp_error(jlong pid, int session, const char *reason);
// ── SPP profile (6 deliveries) ──────────────────────────────────────────
void mob_deliver_bt_spp_connected(jlong pid, int session, const char *address, const char *name);
void mob_deliver_bt_spp_connect_failed(jlong pid, const char *address, const char *reason);
void mob_deliver_bt_spp_disconnected(jlong pid, int session, const char *reason_atom);
void mob_deliver_bt_spp_data(jlong pid, int session, const char *bytes, size_t len);
void mob_deliver_bt_spp_written(jlong pid, int session, int size);
void mob_deliver_bt_spp_error(jlong pid, int session, const char *reason);
// ── HID profile (5 deliveries) ──────────────────────────────────────────
void mob_deliver_bt_hid_connected(jlong pid, int session, const char *address);
void mob_deliver_bt_hid_connect_failed(jlong pid, const char *address, const char *reason);
void mob_deliver_bt_hid_disconnected(jlong pid, int session, const char *reason_atom);
void mob_deliver_bt_hid_input(jlong pid, int session, int type, int code, int value);
void mob_deliver_bt_hid_raw_report(jlong pid, int session, const char *bytes, size_t len);
#endif // MOB_BEAM_H