# Android native script host (development source)

This adapter calls high-level map ABI/session v1 in `sqs_map`. QuickJS is embedded in the map library. Scripts keep `import {map} from 'sqsmap'`; retained listeners explicitly export `sessionMode='persistent'`. The adapter owns one map and at most one script session on one Java executor thread. UI, controls and layer panels are supplied by the application.

Java requires Android API24+. Build the JNI bridge with the matching `sqs_map.h` and a `libsqs_map.so` compiled for the same Android ABI with the `script` Cargo feature. The CMake parameters are `SQS_MAP_INCLUDE_DIR` and `SQS_MAP_NATIVE_LIBRARY`. Package both `libsqs_map.so` and `libsqsmap_mobile.so`,plus any runtime dependencies reported by the selected native build. Keep font/QuickJS and other third-party notices with the library. No native binary is embedded in this source adapter.

```java
NativeMapHost.open(widthPixels,heightPixels,new NativeMapHost.Listener(){
    public void onFrame(int width,int height,byte[] rgba){
        // This callback runs on the map owner thread. Copy/convert RGBA and post UI work.
    }
    public void onEvents(String json){ /* source/camera/input/lifecycle snapshots */ }
    public void onScriptState(String json){ /* initialization,callback progress,errors */ }
    public void onError(Throwable error){ /* display or record the failure */ }
},null).thenAccept(host -> {
    host.runScript("import {map} from 'sqsmap';map.jumpTo({center:[105,25],zoom:4});export default {}; ");
});
```

`runScript` completes when the session starts; initialization/playback completion is reported by `onScriptState`,not by a fixed delay. Re-running stops/releases the old session. Stopping leaves map data/resources in the map. `closeAsync` cancels transport jobs,destroys the map (including bounded script remove callbacks),releases the session and shuts down the owner executor. Use it when the containing view is destroyed. Callbacks must stay short and must not block on owner-thread futures. Every JNI output is copied and its C allocation immediately freed.

`command(Command,json)` accepts the existing C JSON envelope for camera/gesture/source/layer/image/scene/policy calls. POINTER takes the existing input snapshot directly:

```java
host.command(NativeMapHost.Command.POINTER,
    "{\"type\":\"click\",\"point\":{\"x\":64,\"y\":64},\"pointerType\":\"touch\"}");
```

Pointer snapshots publish events; the application sends camera/gesture operations for navigation. Optional AndroidTouchInput recognizes one-finger pan and two-finger zoom/rotation/pitch,with shared policy/activity and tap events. Install it on the application-owned View;close it and detach the listener before closing the host. Custom UI can submit immutable TouchInput frames. See the touch-navigation guide for supported options/anchors and device scope. Existing open/resize overloads retain DPR1. New open(width,height,pixelRatio,listener,transport) and resize(logicalWidth,logicalHeight,pixelRatio) use logical input and dense physical output; onFrame dimensions come from the native state. Convert View coordinates through the actual drawn framebuffer rectangle, then divide by pixelRatio. State exposes physical width/height plus logicalWidth/logicalHeight/pixelRatio; fractional density rounds physical dimensions. Use the matching display-density library (runtime flag0x80000000). `getAttributions` exposes credits for the application's UI,`getStyle` exposes the shared layer/source snapshot. The application must present attribution required by its map providers.

The default HTTP transport follows native URL/retry/deadline/byte plans,uses at most4 workers/32 owned jobs,holds at most64MiB of encoded response reservations and honors no-store. Working copies/native decode/GPU allocations are additional bounded costs. Callers can inject `Transport`;responses are copied,one completion is accepted,and cancelled generations cannot mutate the map. Default WS/WSS is implemented as described below; custom protocols require an injected Transport. Scripts should check core capabilities and the host's stated transport limits. This is the standalone map subset,not the desktop application's complete GIS API.

Local evidence is in `tools/mobile-native-host`: Android Java/ARM64 JNI compilation,actual Linux JVM/JNI/owner/HTTP checks. Linux software-GPU checks are not Android device acceptance. Android device/driver and integration into a mobile GIS application,iOS and formal distribution remain pending.

Build the Android map library from the matching core checkout with `python3 tools/build_android_map.py --ndk <your-NDK-path>`. The Android-only QuickJS bindgen feature uses the selected NDK sysroot and requires a host libclang available to bindgen (or LIBCLANG_PATH). The helper is a separate SDK source attachment.

Use the helper's `release-capi` profile: `target/aarch64-linux-android/release-capi/libsqs_map.so`. A normal `release`/panic-abort binary can link but cannot create a high-level map. The owner validates ABI/session versions and all three unwind/script/session flag bits before creation.


Custom WebSocket transports can call Responder.frame(bytes) repeatedly for requests whose resource.transport is websocket. Wait for each returned Future before submitting another frame. success(bytes) is for one-shot HTTP resources; WebSocket messages must use frame. failure(code,message) terminates and cancels the external task. The host copies input before returning, checks the native request's byte limit, permits one in-flight response per responder and shares a64MiB copied-response budget. Overflow rejects without changing the source. Cancellation discards old-generation responses; closing the host rejects late calls. DefaultTransport now routes HTTP(S) to HttpTransport and WS/WSS live receivers to SocketTransport. Custom Transport remains supported. Pause/resume/reconnect remain source-owned. Android5 adds no C ABI changes.


Default WS/WSS accepts RFC6455 text JSON with fragmentation and ping/pong/close, strict upgrade proof,UTF8 and lengths. Client control frames are masked. Two sockets run independently of HTTP workers; receive-buffer reservations share64MiB and messages obey native maxBytes(up to16MiB). The8-second handshake permits16KiB headers. WSS uses platform certificate trust and HTTPS endpoint identification. Cancellation closes registered TCP/TLS sockets and releases pending tasks/budgets. DNS is resolved by the platform and may finish on its own resolver timeout. Source-owned reconnect/pause/resume uses the same generation and persistent scripts. Extensions/compression,binary data,custom headers/subprotocols,proxy settings and cookie/credential propagation are unavailable through the default receiver; provide Transport for those needs. Source URLs must satisfy the core's WS/WSS validation. Android cleartext/network security configuration and device GPU still require application/device acceptance.


## Embeddable SqsMapView (android.7)

`SqsMapView` is an API24 Android View that draws actual JNI frames using a reused Bitmap and installs the existing touch-navigation adapter. It supplies no toolbar or layer panel. See `examples/SqsMapViewExampleActivity.java` for a self-contained red polygon/blue point that requires no external provider or key. Package the matching JNI/map libraries in your application's `jniLibs` first.

```java
SqsMapView mapView = new SqsMapView(this);
mapView.setListener(new SqsMapView.Listener() {
    public void onReady(SqsMapView view, NativeMapHost host) {
        // Initialize your data and script for this fresh host; see the complete Activity example.
    }
    public void onError(SqsMapView view, Throwable error) { /* application error UI */ }
});
setContentView(mapView);
```

Call `resume()` from Activity.onResume, `pause()` from onPause, and `destroy()` from onDestroy. Attach plus nonzero layout opens automatically. Pause or detach clears the display, cancels touch/resource/script work and closes the complete current host. Resume/reattach waits for prior owner cleanup, creates a fresh host and calls `onReady` again. Map/script/data state is not retained automatically. Initialization failure is reported after cleanup; `resume()` explicitly retries. `destroyAsync()` resolves after release and permanently prevents reopening. Never wait for futures on the main thread.

All View methods and Listener callbacks run on the main thread. NativeMapHost callbacks run on its dedicated owner thread. `getHost()` returns null while opening/closing/resizing; use `isCurrent(host)` in asynchronous application continuations before updating UI. Set `TransportFactory` before attachment; each generation owns and closes its own transport. Applications remain responsible for provider attribution via host.getAttributions().

The full View rectangle is the drawing/touch area. Its physical size and display density (0.25..8) determine rounded logical dimensions and native DPR. Size/configuration changes serialize native viewport updates; obsolete frames cannot display. A native physical edge is limited to4096 and RGBA to16MiB, validated before open. The latest-frame slot, one ARGB array and one Bitmap nominally use up to48MiB plus a64KiB color lookup; native/GPU, transient allocations and GC costs are additional. UI frame scheduling has one outstanding drain. Events/script notifications retain FIFO order within32 slots,256KiB each/4MiB total; overflow explicitly reports RESOURCE_LIMIT and closes that generation. Public owner operations are bounded to32 pending calls; a33rd fails with RESOURCE_LIMIT. Close uses a reserved path and settles queued futures.

The matching headless native library emits premultiplied sRGB RGBA, including flat vectors. The four-argument onFrame callback reports SRGB_PREMULTIPLIED_RGBA; the old three-argument callback remains supported. SqsMapView explicitly maps RGBA to straight ARGB for Bitmap.setPixels, using sRGB decode, alpha division and re-encoding. UNORM_PREMULTIPLIED_RGBA is reserved for externally supplied frames and is not emitted by this NativeMapHost. Opaque bytes are unchanged; fully transparent RGB is cleared.

`tools/android-view` verifies API24 Java/sample and ARM64 JNI compilation, deterministic lifecycle ordering of the production View with framework shims, and actual Linux JNI/software-GPU frames (half-alpha red, opaque blue, DPR resize, media frame, owner limits, late resource cancellation and failure cleanup). These checks do not prove Android Canvas/MotionEvent/window/device GPU, transparent3D display or integration into a mobile GIS app; those remain pending.
