From f6cfa81aaabc89689b35a3281f39ca1b05e94455 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 25 May 2026 21:10:36 +0530 Subject: [PATCH 01/10] Added rdkNativescript documentation --- docs/README.md | 388 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..977e91c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,388 @@ +# RdkNativeScript + +rdkNativeScript is a JavaScript runtime component in the RDK middleware that enables native execution of JavaScript applications directly on RDK-V devices, outside of a full browser environment. It provides a lightweight, embeddable runtime that exposes device capabilities — such as media playback, networking, and display — to JavaScript applications through a set of controlled API bindings. The component is deployed as a Thunder plugin with the callsign `org.rdk.jsruntime` and can be cloned to create multiple independent runtime instances. + +At the device level, rdkNativeScript allows non-browser JavaScript applications such as lightweight widgets and streaming clients to run with native-level access to media pipelines, WebSocket communication, and the Wayland display stack. It bridges the gap between JavaScript application logic and low-level device capabilities without requiring a full web engine. + +At the module level, rdkNativeScript manages the complete lifecycle of JavaScript execution contexts: it initializes the JavaScript engine, creates per-application contexts, loads and evaluates scripts (from local paths or remote URLs), manages optional module bindings per context, and provides a WebSocket-based IPC channel for external control. + +```mermaid +flowchart LR + +%% Styles +classDef Apps stroke:#00B9F1,fill:#E6F7FD,stroke-width:2px; +classDef RDKMW stroke:#75D701,fill:#F1FFE6,stroke-width:2px; +classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; + +%% Apps Layer + subgraph Apps["Apps & Runtimes"] + WPE_RT["WPEFramework / Thunder"] + end + +%% Middleware + subgraph RDKMW["RDK Core Middleware"] + JSRuntime["rdkNativeScript\n(org.rdk.jsruntime)"] + AAMP["AAMP Media Player"] + Westeros["Westeros / Wayland"] + Thunder["Thunder Core"] + end + +%% Vendor Layer + subgraph VL["Vendor Layer"] + Essos["Essos (Wayland Compositor Abstraction)"] + GST["GStreamer Pipeline"] + EGL["EGL / GPU"] + end + + %% Connections + WPE_RT -->|JSON-RPC: launchApplication| Thunder + Thunder -->|Dispatch| JSRuntime + JSRuntime -->|Media playback bindings| AAMP + JSRuntime -->|Wayland display + key input| Westeros + AAMP -->|Pipeline control| GST + Westeros -->|Compositor abstraction| Essos + Essos -->|EGL rendering| EGL +``` + +**Key Features & Responsibilities:** + +- **Multi-context JavaScript Execution**: Hosts multiple independent JavaScript application contexts within a single process. Each application receives its own JSC global context with its own module bindings, allowing widgets and lightweight apps to run concurrently without interference. + +- **Engine Abstraction**: Decouples the application runtime from the underlying JavaScript engine through the `IJavaScriptEngine` and `IJavaScriptContext` interfaces. The primary engine is JavaScriptCore (JSC); the build system also supports QuickJS as an alternate engine. + +- **Per-Application Module Configuration**: Each application context is configured at creation time with a set of optional module bindings. Supported modules include HTTP, XHR, WebSocket, WebSocketEnhanced, Fetch, JSDOM, MiniJSDOM, Window, and media Player. Modules are activated by passing an options string to `launchApplication`. + +- **AAMP Media Player Integration**: Exposes `AAMPMediaPlayer` as a JavaScript global when the player module is enabled. AAMP bindings are deployed as a DAC (Downloadable Application Container) module, decoupling the player library from the runtime binary. + +- **WebSocket Server and Client IPC**: Provides an optional WebSocket server (on the port defined by `WS_SERVER_PORT`) that accepts JSON-encoded commands to launch, run, and terminate applications remotely. A corresponding client is also provided for applications that need to connect to the server. + +- **Wayland Display and Input Handling**: Integrates with the Essos compositor abstraction layer to set up a Wayland display surface and route keyboard input events from the compositor into the active JavaScript context. + +- **Remote JavaScript Inspector**: Optionally starts a JSC remote inspector server to enable JavaScript debugging over a network connection, controlled via the `NATIVEJS_INSPECTOR_SERVER` environment variable. + +- **Container Namespace Entry**: Supports running applications inside Linux containers by entering network, mount, IPC, and PID namespaces of a running container process, enabling script delivery over WebSocket to containerized runtime instances. + +--- + +## Design + +rdkNativeScript is structured around a layered separation between engine management, context lifecycle, and application dispatch. The runtime is initialized once per process through `NativeJSRenderer`, which owns the `IJavaScriptEngine` instance and manages the map of active application contexts. Each application is represented by a numeric identifier mapped to a `JavaScriptContext` instance. The `JavaScriptContextBase` class provides engine-agnostic operations — file loading, script evaluation delegation, key event routing, and ThunderJS / RDK WebBridge code injection — while engine-specific implementations extend it for JSC or QuickJS. + +Northbound, the component exposes its API through the Thunder plugin mechanism: clients issue a JSON-RPC `launchApplication` call to a cloned plugin instance. The server path, when enabled, accepts the same JSON command structure over a WebSocket connection on the port defined by `WS_SERVER_PORT`, enabling external tooling and testing frameworks to drive the runtime without a Thunder session. The `JSRuntimeServer` dispatches incoming messages to the same `NativeJSRenderer` methods used by the Thunder plugin path. Southbound, the component consumes the JavaScriptCore C API for script evaluation, GStreamer for media pipeline initialization, libcurl for script download from remote URLs, and the Essos API for Wayland compositor setup and keyboard event delivery. + +The design isolates per-application state (URL, JS context, module flags, performance metrics) inside `JavaScriptContext` and uses a shared `JSContextGroupRef` across all contexts in the process. This allows garbage collection to be coordinated globally through a periodic GLib timer while individual contexts can be released independently. The main GLib event loop processes both JSC internal events and timer callbacks on the main thread; applications are created and run from separate per-application threads that call into the renderer. + +IPC is handled through two mechanisms. Within the device, Thunder JSON-RPC is the primary channel for application control. The WebSocket server and client provide an alternative channel used for remote control and container-bridged delivery. Container-side delivery is implemented in `JSRuntimeContainer`, which reads the container process PID from the cgroup filesystem, enters the container's network namespace using `setns`, and connects a WebSocket client to the in-container server endpoint. + +Module settings, application URLs, and runtime flags are held in memory for the lifetime of the process. Runtime configuration is managed through environment variables or sentinel files in `/tmp`. + +```mermaid +graph TD + + subgraph JSRuntime ["rdkNativeScript Process"] + + subgraph RendererLayer ["NativeJSRenderer (Application Manager)"] + NR["NativeJSRenderer\nManages context map, pending requests,\napplication lifecycle (create/run/terminate)"] + end + + subgraph EngineLayer ["JavaScript Engine"] + JSE["JavaScriptEngine (JSC)\nGLib main loop, GStreamer init,\nperiodic GC, remote inspector setup"] + end + + subgraph ContextLayer ["Per-Application Contexts"] + CTX1["JavaScriptContext (App 1)\nJSC global context, module bindings,\nAAMP player, network metrics"] + CTX2["JavaScriptContext (App N)\nJSC global context, module bindings"] + end + + subgraph BaseLayer ["JavaScriptContextBase"] + BASE["Engine-agnostic ops:\nfile load, runScript, runFile,\nThunderJS injection, key routing"] + end + + subgraph SupportLayer ["Support Modules"] + ES["EssosInstance\nWayland display init,\nkeyboard event callbacks"] + MS["ModuleSettings\nPer-app feature flags parsed\nfrom options string"] + LOG["NativeJSLogger\nLevel-filtered logging,\noptional EthanLog output"] + end + + end + + NR --> JSE + NR --> CTX1 + NR --> CTX2 + CTX1 --> BASE + CTX2 --> BASE + NR --> ES + NR --> MS +``` + +### Threading Model + +- **Threading Architecture**: Multi-threaded with a main GLib event loop thread plus per-application worker threads and an optional WebSocket server thread. +- **Main Thread**: Runs the GLib main loop, which processes JSC internal callbacks, timer events (including the periodic GC timer), and uv event loop ticks. All JSC context creation and evaluation calls issued from the application threads re-enter the engine via the shared context group, with main-thread callbacks posted through `rtThreadQueue`. +- **Worker Threads**: + - _Application thread_: One thread per launched application calls `renderer->createApplication()` and `renderer->runApplication()`. Evaluation of the script occurs on this thread; the result is surfaced when the script returns or the context is terminated. + - _Console thread_: When developer console mode is enabled, a dedicated thread processes queued JavaScript snippets submitted interactively. + - _WebSocket server thread_: When the server is enabled, a detached thread runs `WsServer::run()` to handle incoming WebSocket connections. + - _Container namespace thread_: A temporary thread is spawned per `nsEnter` call to execute `setns` and perform the namespace-bound operation, then joins immediately. +- **Synchronization**: `NativeJSRenderer` protects the context map with `mUserMutex`. The console state uses `isProcessing_cv` (condition variable + mutex) for producer/consumer coordination of queued scripts. `JSRuntimeServer` protects the connection set with `mDataMutex`. `JSRuntimeClient` uses `mResponseMutex` and `mResponseCondition` with a 5-second wait-for-response timeout. +- **Async / Event Dispatch**: Key events from Essos are dispatched synchronously into the registered `JavaScriptKeyListener` (the active context). Timer callbacks and deferred JS execution are scheduled through the GLib main loop rather than blocking caller threads. + +### RDK-V Platform and Integration Requirements + +- **Build Dependencies**: westeros, essos, rapidjson, rtcore, libuv, gstreamer1.0, uwebsockets, JavaScriptCore, websocketpp, cjson, boost, virtual/egl. When container widget support is enabled, dobby is additionally required. +- **Plugin Dependencies**: The AAMP media player library (`libaampjsbindings.so`) must be present at the target library path when dynamic AAMP bindings are enabled. +- **Device Services / HAL**: Essos HAL for Wayland compositor abstraction and keyboard input; GStreamer 1.0 for media pipeline initialization. +- **Systemd Services**: A running Wayland compositor (Westeros) must be available when Essos integration is enabled and a display is requested. + +### Module Settings + +`ModuleSettings` is a plain data structure that controls which JavaScript binding modules are registered for a given application context. Each application receives its own `ModuleSettings` instance populated at launch time; the settings are fixed for the lifetime of that context. + +**Available Modules:** + +| Option Token | Field | What It Enables | +| ------------ | ------------------------- | -------------------------------------------------------------------------------------- | +| `http` | `enableHttp` | HTTP client bindings in the JavaScript context | +| `xhr` | `enableXHR` | XMLHttpRequest (XHR) bindings | +| `ws` | `enableWebSocket` | WebSocket client bindings | +| `wsenhanced` | `enableWebSocketEnhanced` | Enhanced WebSocket bindings with additional event support | +| `fetch` | `enableFetch` | Fetch API bindings | +| `jsdom` | `enableJSDOM` | Full JSDOM bindings for DOM API emulation | +| `minijsdom` | `enableMiniJSDOM` | Lightweight JSDOM subset; takes precedence over `jsdom` when both tokens are specified | +| `window` | `enableWindow` | Window object bindings | +| `player` | `enablePlayer` | AAMP media player bindings; exposes `AAMPMediaPlayer` as a JavaScript global | + +**Population Mechanisms:** + +- **Via Thunder JSON-RPC or WebSocket command**: The `options` parameter of `launchApplication` is a comma-separated string of token names (e.g., `"player,xhr,ws"`). `ModuleSettings::fromString()` parses this string and sets the corresponding boolean flags. +- **Via standalone launcher (jsruntime-launcher)**: The launcher reads an `app.config` JSON file at `/package/app.config` and maps `features` array entries (e.g., `{"name": "player", "enable": true}`) to command-line flags (`--enablePlayer`, `--enableXHR`, etc.), which are then parsed into `ModuleSettings` fields before the application context is created. + +All flags default to `false`; only tokens present in the options string activate the corresponding module. `minijsdom` and `jsdom` are mutually exclusive — `minijsdom` takes precedence when both tokens appear. + +--- + +### Component State Flow + +#### Initialization to Active State + +```mermaid +sequenceDiagram + participant System as System / PluginActivator + participant Thunder as Thunder + participant NR as NativeJSRenderer + participant JSE as JavaScriptEngine-JSC + participant Essos as EssosInstance + participant GST as GStreamer + + System->>Thunder: Controller.1.clone org.rdk.jsruntime to jsruntime1 + System->>Thunder: Controller.1.activate jsruntime1 + Thunder->>NR: Construct NativeJSRenderer with waylandDisplay + Note over NR: Read NATIVEJS_LOG_LEVEL env var + NR->>Essos: EssosInstance.initialize useWayland + Essos-->>NR: Essos context ready + NR->>JSE: new JavaScriptEngine and initialize + JSE->>GST: gst_init if player enabled + JSE->>JSE: WTF.initializeMainThread + JSE->>JSE: g_main_loop_new and install GC timer + Note over JSE: Remote inspector started if NATIVEJS_INSPECTOR_SERVER set + JSE-->>NR: Engine initialized + Note over NR: Check /tmp sentinel files for ThunderJS, WebBridge, WS server + NR-->>Thunder: Ready + + loop Runtime + Note over NR: State: Active - awaiting launchApplication calls + end +``` + +#### Runtime State Changes + +**State Change Triggers:** + +- A `launchApplication` JSON-RPC call (or equivalent WebSocket command) causes `NativeJSRenderer` to allocate a new application ID, create a `JavaScriptContext` with the specified module settings, download the script via libcurl if it is a remote URL, and evaluate it in the context. +- A `terminateApplication` call releases the `JavaScriptContext` for the given ID, runs synchronous garbage collection on the global context if it was the top-level context, and removes the entry from the context map. +- When the Wayland display becomes unavailable while Essos is active, key events from Essos stop being delivered to registered contexts. + +**Context Switching Scenarios:** + +- When multiple applications are active simultaneously, each holds an independent `JSGlobalContextRef` within the shared `JSContextGroupRef`. Module settings are fixed at context creation time for the lifetime of the application. +- In developer console mode, the console thread continuously reads from a deque of queued scripts and evaluates them in a dedicated console context, separate from launched application contexts. + +--- + +### Call Flows + +#### Initialization Call Flow + +```mermaid +sequenceDiagram + participant Client as ThunderJS / curl + participant Thunder as Thunder + participant NR as NativeJSRenderer + participant JSE as JavaScriptEngine + + Client->>Thunder: Controller.1.clone {callsign: "org.rdk.jsruntime", newcallsign: "jsruntime1"} + Thunder-->>Client: Clone acknowledged + Client->>Thunder: Controller.1.activate {callsign: "jsruntime1"} + Thunder->>NR: Construct and initialize + NR->>JSE: initialize() + JSE-->>NR: Engine ready + NR-->>Thunder: Plugin active + Thunder-->>Client: Activation success +``` + +#### Request Processing Call Flow + +```mermaid +sequenceDiagram + participant Client as ThunderJS / curl + participant Thunder as Thunder + participant NR as NativeJSRenderer + participant CTX as JavaScriptContext + participant CURL as libcurl + participant AAMP as AAMP JS Bindings + + Client->>Thunder: JSON-RPC: jsruntime1.1.launchApplication {url, options} + Thunder->>NR: Dispatch launchApplication + NR->>NR: createApplicationIdentifier() + NR->>CTX: new JavaScriptContext(moduleSettings, url, engine) + Note over CTX: Register bindings for enabled modules\n(XHR, WebSocket, Player, Fetch, JSDOM…) + alt Player module enabled + CTX->>AAMP: loadAAMPJSBindingsLib() / AAMPPlayer_LoadJS(context) + end + NR->>CURL: downloadFile(url) [if remote URL] + CURL-->>NR: Script content + NR->>CTX: runFile(scriptPath, args, isApplication=true) + CTX-->>NR: Execution complete + NR-->>Thunder: JSON-RPC response {success: true} + Thunder-->>Client: Response +``` + +--- + +## Internal Modules + +| Module / Class | Description | Key Files | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | +| `NativeJSRenderer` | Central application manager. Owns the JavaScript engine instance and the map of active contexts. Exposes `createApplication`, `runApplication`, `runJavaScript`, and `terminateApplication`. Manages pending request queues, Essos initialization, and developer console thread. | `NativeJSRenderer.cpp`, `NativeJSRenderer.h` | +| `JavaScriptEngine` | Concrete JSC engine implementation. Initializes the WTF main thread, GLib event loop, GStreamer pipeline subsystem, remote inspector server, and the periodic garbage collection timer. Implements `IJavaScriptEngine`. | `src/jsc/JavaScriptEngine.cpp`, `include/jsc/JavaScriptEngine.h` | +| `JavaScriptContext` | Per-application JSC global context. Registers all enabled module bindings (setTimeout, XHR, WebSocket, HTTP, Fetch, JSDOM, crypto, player). Tracks performance metrics (context creation time, execution time, playback start time) and network metrics via `NetworkMetricsListener`. Implements `IJavaScriptContext`. | `src/jsc/JavaScriptContext.cpp`, `include/jsc/JavaScriptContext.h` | +| `JavaScriptContextBase` | Engine-agnostic base class for JavaScript contexts. Implements file loading, `runScript`, `runFile`, key event routing to the active context, ThunderJS and RDK WebBridge code injection, and module path resolution. | `src/JavaScriptContextBase.cpp`, `include/JavaScriptContextBase.h` | +| `JSRuntimeServer` | WebSocket server (singleton) that listens on a configurable port and dispatches JSON-encoded `launchApplication`, `createApplication`, `runApplication`, `runJavaScript`, and `terminateApplication` commands to `NativeJSRenderer`. Uses websocketpp with Asio transport. | `src/JSRuntimeServer.cpp`, `include/JSRuntimeServer.h` | +| `JSRuntimeClient` | WebSocket client (singleton) that connects to a `JSRuntimeServer` instance and provides a synchronous `sendCommand` interface with a 5-second response timeout. Used by `JSRuntimeContainer` to relay launch commands into a container. | `src/JSRuntimeClient.cpp`, `include/JSRuntimeClient.h` | +| `JSRuntimeContainer` | Provides utilities for entering Linux namespaces (network, mount, IPC, PID) of a containerized process by resolving the container PID from the cgroup filesystem and calling `setns` on a temporary thread. Also builds and dispatches WebSocket launch messages to the in-container server. | `src/JSRuntimeContainer.cpp`, `include/JSRuntimeContainer.h` | +| `EssosInstance` | Singleton wrapper around the Essos compositor abstraction API. Initializes an Essos context against the active Wayland display and translates raw Wayland key events into `JavaScriptKeyDetails` structures that are forwarded to the registered `JavaScriptKeyListener`. | `src/EssosInstance.cpp`, `include/EssosInstance.h` | +| `ModuleSettings` | Plain data structure holding boolean flags for each optional JavaScript module. Populated either from command-line flags in standalone mode or by parsing a comma-separated options string passed to `launchApplication`. | `src/ModuleSettings.cpp`, `include/ModuleSettings.h` | +| `NativeJSLogger` | Component-level logger with five severity levels (DEBUG, INFO, WARN, ERROR, FATAL). Level is set via the `NATIVEJS_LOG_LEVEL` environment variable at startup. Supports output to either stdout or EthanLog when the `ETHAN_LOGGING_PIPE` environment variable is present. | `src/NativeJSLogger.cpp`, `include/NativeJSLogger.h` | +| `PlayerWrapper` | Manages a `PlayerInstanceAAMP` player object within a JSC context. Initializes AAMP, registers JavaScript-callable player functions (`load`, `play`, `pause`, `stop`, `seek`, audio/text track selection, etc.), and routes player events back into the JS context via `PlayerEventHandler`. | `src/jsc/PlayerWrapper.cpp`, `include/jsc/PlayerWrapper.h` | + +--- + +## Component Interactions + +### Interaction Matrix + +| Target Component / Layer | Interaction Purpose | Key APIs / Topics | +| ------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| **Plugins** | | | +| `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | +| **Device Services / HAL** | | | +| Essos | Wayland display initialization and keyboard input routing | `EssCtxCreate`, `EssCtxSetKeyboardListener`, `EssCtxStart` | +| GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | +| AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | +| libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | +| **External Systems** | | | +| WebSocket Server (self) | External tools and container clients send application control commands | WebSocket JSON messages: `launchApplication`, `createApplication`, `terminateApplication` | +| Remote Inspector | JavaScript debugger connection over network | `JSRemoteInspectorStart()`, env `NATIVEJS_INSPECTOR_SERVER` | + +### Events Published + +| Event Name | Topic | Trigger Condition | Subscriber Components | +| ------------------- | ----------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- | +| Key press / release | Internal `JavaScriptKeyListener` callback | Wayland key event received by EssosInstance | Active `JavaScriptContextBase` (processes key event in JS engine) | + +### IPC Flow Patterns + +**WebSocket Server Command Flow:** + +```mermaid +sequenceDiagram + participant ExtTool as External Tool / Container Client + participant SRV as JSRuntimeServer + participant NR as NativeJSRenderer + participant CTX as JavaScriptContext + + ExtTool->>SRV: WebSocket connect (WS_SERVER_PORT) + ExtTool->>SRV: JSON: {"method": "launchApplication", "params": {"url": "...", "options": "player,xhr"}} + SRV->>NR: createApplication(moduleSettings) + SRV->>NR: runApplication(id, url) + NR->>CTX: Script execution + CTX-->>NR: Done + SRV-->>ExtTool: JSON response {success, id} +``` + +--- + +## Implementation Details + +### Major HAL APIs Integration + +| HAL / DS API | Purpose | Implementation File | +| ------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------- | +| `EssCtxCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | +| `EssCtxSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | +| `EssCtxSetKeyboardListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | +| `EssCtxStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | +| `gst_init()` | Initializes the GStreamer framework before any pipeline creation | `src/jsc/JavaScriptEngine.cpp` | +| `AAMPPlayer_LoadJS()` | Loads AAMP JS bindings into a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | +| `AAMPPlayer_UnloadJS()` | Unloads AAMP JS bindings from a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | +| `dlopen("libaampjsbindings.so")` | Dynamically loads the AAMP JS bindings library at application creation | `src/jsc/JavaScriptContext.cpp` | +| `JSGlobalContextCreateInGroup()` | Creates a new JSC global context within the shared context group | `src/jsc/JavaScriptContext.cpp` | +| `JSContextGroupCreate()` | Creates the shared JSC context group for the process | `src/jsc/JavaScriptContext.cpp` | +| `JSSynchronousGarbageCollectForDebugging()` | Forces synchronous GC on context release | `src/jsc/JavaScriptContext.cpp` | +| `curl_easy_perform()` | Downloads remote script content before evaluation | `src/NativeJSRenderer.cpp` | + +### Key Implementation Logic + +- **State / Lifecycle Management**: `NativeJSRenderer` maintains a `std::map` (`mContextMap`) mapping application IDs to their `IJavaScriptContext` instances. IDs are allocated by `createApplicationIdentifier()` which increments a counter. Application creation, execution, and termination operations arrive as `ApplicationRequest` structs queued in `gPendingRequests` and processed by internal handlers. On termination, the context pointer is deleted and the map entry is removed. + - Core lifecycle: `src/NativeJSRenderer.cpp` + +- **Event Processing**: Keyboard events from Essos flow through `EssosInstance` static callbacks, which call `onKeyPress` / `onKeyRelease` on the registered `JavaScriptKeyListener`. `JavaScriptContextBase` implements that listener and forwards events to the engine-specific `processKeyEvent()` implementation. JSC contexts then inject a synthetic DOM key event object into the executing script context. + +- **Error Handling Strategy**: Logger calls at WARN and ERROR levels mark failure points. When a script file cannot be loaded, the failure is logged and the operation returns. When the AAMP dynamic library is unavailable, the failure is logged and context creation proceeds with the remaining enabled bindings. libcurl download failures are logged and result in an empty script evaluation. WebSocket send failures in `JSRuntimeServer` are caught and logged, preserving the active connection. + +- **Logging & Diagnostics**: The logger prefix is `JSRuntime [Thread-]` on all log lines. The log level is controlled by the `NATIVEJS_LOG_LEVEL` environment variable (DEBUG, INFO, WARN, ERROR, FATAL); the default level is INFO. When `ETHAN_LOGGING_PIPE` is set, output is redirected to the EthanLog daemon using mapped severity levels. Key log points include engine initialization, GC timer installation, remote inspector startup, Essos context creation, application creation and termination, script download status, and WebSocket server events. + +--- + +## Configuration + +### Key Configuration Parameters + +| Parameter | Type | Default | Description | +| ----------------------------- | ------------ | ----------- | -------------------------------------------------------------------------------------------------------------- | +| `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | +| `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | +| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | +| `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | +| `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp` sentinel file. | +| `WAYLAND_DISPLAY` | string (env) | _(not set)_ | Set automatically from the `--display` argument to direct the runtime to a specific Wayland compositor socket. | +| `WS_SERVER_PORT` | int (build) | `5000` | WebSocket server listen port. Defined at build time via `-DWS_SERVER_PORT=5000`. | +| `NATIVEJS_DUMP_NETWORKMETRIC` | string (env) | _(not set)_ | When set, collects network metrics and stores the output to a file in `/tmp`. | + +### Runtime Configuration + +The options string passed to `launchApplication` configures the module bindings for the created JavaScript context: + +```bash +# Launch with player and XHR modules enabled +curl -H "Content-Type: application/json" \ + --request POST \ + --data '{"jsonrpc":"2.0","id":"1","method":"jsruntime1.1.launchApplication","params":{"url":"http://host/app.js","options":"player,xhr"}}' \ + http://127.0.0.1:9998/jsonrpc +``` + +Accepted option tokens: `http`, `xhr`, `ws`, `wsenhanced`, `fetch`, `jsdom`, `minijsdom`, `window`, `player`. + +### Configuration Persistence + +Configuration changes are not persisted across reboots. From 8fde11873b094d21296b2a374bf11dcfcedf5876 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Tue, 9 Jun 2026 16:17:17 +0530 Subject: [PATCH 02/10] functions checked and confirmed --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 977e91c..05158b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -286,7 +286,7 @@ sequenceDiagram | **Plugins** | | | | `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | | **Device Services / HAL** | | | -| Essos | Wayland display initialization and keyboard input routing | `EssCtxCreate`, `EssCtxSetKeyboardListener`, `EssCtxStart` | +| Essos | Wayland display initialization and keyboard input routing | `EssContextCreate`, `EssContextSetKeyListener`, `EssContextStart` | | GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | | AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | | libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | @@ -328,10 +328,10 @@ sequenceDiagram | HAL / DS API | Purpose | Implementation File | | ------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------- | -| `EssCtxCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | -| `EssCtxSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | -| `EssCtxSetKeyboardListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | -| `EssCtxStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | +| `EssContextCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | +| `EssContextSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | +| `EssContextSetKeyListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | +| `EssContextStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | | `gst_init()` | Initializes the GStreamer framework before any pipeline creation | `src/jsc/JavaScriptEngine.cpp` | | `AAMPPlayer_LoadJS()` | Loads AAMP JS bindings into a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | | `AAMPPlayer_UnloadJS()` | Unloads AAMP JS bindings from a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | From e2ebbc09949f90141eab36dd33f93a1b92c8cfeb Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Fri, 24 Jul 2026 11:09:43 +0530 Subject: [PATCH 03/10] Fixed review comments --- docs/README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/README.md b/docs/README.md index 05158b5..c713f76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # RdkNativeScript -rdkNativeScript is a JavaScript runtime component in the RDK middleware that enables native execution of JavaScript applications directly on RDK-V devices, outside of a full browser environment. It provides a lightweight, embeddable runtime that exposes device capabilities — such as media playback, networking, and display — to JavaScript applications through a set of controlled API bindings. The component is deployed as a Thunder plugin with the callsign `org.rdk.jsruntime` and can be cloned to create multiple independent runtime instances. +rdkNativeScript is a JavaScript runtime component in the RDK middleware that enables native execution of JavaScript applications directly on RDKE/RDKV devices, outside of a full browser environment. It provides a lightweight, embeddable runtime that exposes device capabilities — such as media playback, networking, and display — to JavaScript applications through a set of controlled API bindings. The component is deployed as a Thunder plugin with the callsign `org.rdk.jsruntime` and can be cloned to create multiple independent runtime instances. At the device level, rdkNativeScript allows non-browser JavaScript applications such as lightweight widgets and streaming clients to run with native-level access to media pipelines, WebSocket communication, and the Wayland display stack. It bridges the gap between JavaScript application logic and low-level device capabilities without requiring a full web engine. @@ -127,11 +127,11 @@ graph TD - **Synchronization**: `NativeJSRenderer` protects the context map with `mUserMutex`. The console state uses `isProcessing_cv` (condition variable + mutex) for producer/consumer coordination of queued scripts. `JSRuntimeServer` protects the connection set with `mDataMutex`. `JSRuntimeClient` uses `mResponseMutex` and `mResponseCondition` with a 5-second wait-for-response timeout. - **Async / Event Dispatch**: Key events from Essos are dispatched synchronously into the registered `JavaScriptKeyListener` (the active context). Timer callbacks and deferred JS execution are scheduled through the GLib main loop rather than blocking caller threads. -### RDK-V Platform and Integration Requirements +### RDKE/RDKV Platform and Integration Requirements - **Build Dependencies**: westeros, essos, rapidjson, rtcore, libuv, gstreamer1.0, uwebsockets, JavaScriptCore, websocketpp, cjson, boost, virtual/egl. When container widget support is enabled, dobby is additionally required. - **Plugin Dependencies**: The AAMP media player library (`libaampjsbindings.so`) must be present at the target library path when dynamic AAMP bindings are enabled. -- **Device Services / HAL**: Essos HAL for Wayland compositor abstraction and keyboard input; GStreamer 1.0 for media pipeline initialization. +- **HAL**: Essos HAL for Wayland compositor abstraction and keyboard input; GStreamer 1.0 for media pipeline initialization. - **Systemd Services**: A running Wayland compositor (Westeros) must be available when Essos integration is enabled and a display is requested. ### Module Settings @@ -281,18 +281,18 @@ sequenceDiagram ### Interaction Matrix -| Target Component / Layer | Interaction Purpose | Key APIs / Topics | -| ------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| **Plugins** | | | -| `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | -| **Device Services / HAL** | | | -| Essos | Wayland display initialization and keyboard input routing | `EssContextCreate`, `EssContextSetKeyListener`, `EssContextStart` | -| GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | -| AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | -| libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | -| **External Systems** | | | -| WebSocket Server (self) | External tools and container clients send application control commands | WebSocket JSON messages: `launchApplication`, `createApplication`, `terminateApplication` | -| Remote Inspector | JavaScript debugger connection over network | `JSRemoteInspectorStart()`, env `NATIVEJS_INSPECTOR_SERVER` | +| Target Component / Layer | Interaction Purpose | Key APIs / Topics | +| ------------------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| **Plugins** | | | +| `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | +| **HAL** | | | +| Essos | Wayland display initialization and keyboard input routing | `EssCtxCreate`, `EssCtxSetKeyboardListener`, `EssCtxStart` | +| GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | +| AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | +| libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | +| **External Systems** | | | +| WebSocket Server (self) | External tools and container clients send application control commands | WebSocket JSON messages: `launchApplication`, `createApplication`, `terminateApplication` | +| Remote Inspector | JavaScript debugger connection over network | `JSRemoteInspectorStart()`, env `NATIVEJS_INSPECTOR_SERVER` | ### Events Published @@ -324,14 +324,14 @@ sequenceDiagram ## Implementation Details -### Major HAL APIs Integration +### Key External API Integrations -| HAL / DS API | Purpose | Implementation File | +| API | Purpose | Implementation File | | ------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------- | -| `EssContextCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | -| `EssContextSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | -| `EssContextSetKeyListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | -| `EssContextStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | +| `EssCtxCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | +| `EssCtxSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | +| `EssCtxSetKeyboardListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | +| `EssCtxStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | | `gst_init()` | Initializes the GStreamer framework before any pipeline creation | `src/jsc/JavaScriptEngine.cpp` | | `AAMPPlayer_LoadJS()` | Loads AAMP JS bindings into a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | | `AAMPPlayer_UnloadJS()` | Unloads AAMP JS bindings from a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | From 227c13ac5c18e77df5d1cb9bc86ae33417f0dc16 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Fri, 24 Jul 2026 12:54:06 +0530 Subject: [PATCH 04/10] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index c713f76..cd6afe6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# RdkNativeScript +# rdkNativeScript rdkNativeScript is a JavaScript runtime component in the RDK middleware that enables native execution of JavaScript applications directly on RDKE/RDKV devices, outside of a full browser environment. It provides a lightweight, embeddable runtime that exposes device capabilities — such as media playback, networking, and display — to JavaScript applications through a set of controlled API bindings. The component is deployed as a Thunder plugin with the callsign `org.rdk.jsruntime` and can be cloned to create multiple independent runtime instances. @@ -358,16 +358,18 @@ sequenceDiagram ### Key Configuration Parameters -| Parameter | Type | Default | Description | -| ----------------------------- | ------------ | ----------- | -------------------------------------------------------------------------------------------------------------- | -| `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | -| `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | -| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | -| `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | -| `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp` sentinel file. | -| `WAYLAND_DISPLAY` | string (env) | _(not set)_ | Set automatically from the `--display` argument to direct the runtime to a specific Wayland compositor socket. | -| `WS_SERVER_PORT` | int (build) | `5000` | WebSocket server listen port. Defined at build time via `-DWS_SERVER_PORT=5000`. | -| `NATIVEJS_DUMP_NETWORKMETRIC` | string (env) | _(not set)_ | When set, collects network metrics and stores the output to a file in `/tmp`. | +| Parameter | Type | Default | Description | +| ----------------------------- | -------------- | --------------- | -------------------------------------------------------------------------------------------------------------- | +| `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | +| `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | +| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | +| `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | +| `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp/nativejsEmbedThunder` sentinel file. | +| `NATIVEJS_ENABLE_WEBSOCKET_SERVER` | string (env) | _(not set)_ | When set, enables the WebSocket server. Equivalent to creating the `/tmp/nativejsEnableWebSocketServer` sentinel file. | +| `/tmp/nativejsRdkWebBridge` | file (sentinel)| _(not present)_ | When present, enables rdk WebBridge injection into all contexts. | +| `WAYLAND_DISPLAY` | string (env) | _(not set)_ | Set automatically from the `--display` argument to direct the runtime to a specific Wayland compositor socket. | +| `WS_SERVER_PORT` | int (build) | `5000` | WebSocket server listen port. Defined at build time via `-DWS_SERVER_PORT=5000`. | +| `NATIVEJS_DUMP_NETWORKMETRIC` | string (env) | _(not set)_ | When set, collects network metrics and stores the output to a file in `/tmp`. | ### Runtime Configuration From 0287704c7b05f48c3aedb23f0521bf608233f0d2 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Fri, 24 Jul 2026 13:01:19 +0530 Subject: [PATCH 05/10] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index cd6afe6..62b3c58 100644 --- a/docs/README.md +++ b/docs/README.md @@ -350,7 +350,7 @@ sequenceDiagram - **Error Handling Strategy**: Logger calls at WARN and ERROR levels mark failure points. When a script file cannot be loaded, the failure is logged and the operation returns. When the AAMP dynamic library is unavailable, the failure is logged and context creation proceeds with the remaining enabled bindings. libcurl download failures are logged and result in an empty script evaluation. WebSocket send failures in `JSRuntimeServer` are caught and logged, preserving the active connection. -- **Logging & Diagnostics**: The logger prefix is `JSRuntime [Thread-]` on all log lines. The log level is controlled by the `NATIVEJS_LOG_LEVEL` environment variable (DEBUG, INFO, WARN, ERROR, FATAL); the default level is INFO. When `ETHAN_LOGGING_PIPE` is set, output is redirected to the EthanLog daemon using mapped severity levels. Key log points include engine initialization, GC timer installation, remote inspector startup, Essos context creation, application creation and termination, script download status, and WebSocket server events. +- **Logging & Diagnostics**: Console logs are emitted as `[LEVEL] JsRuntime Thread-: `; when `ETHAN_LOGGING_PIPE` is set (EthanLog enabled), the message is prefixed with `JSRuntime [Thread-]`. The log level is controlled by the `NATIVEJS_LOG_LEVEL` environment variable (DEBUG, INFO, WARN, ERROR, FATAL); the default level is INFO. When `ETHAN_LOGGING_PIPE` is set, output is redirected to the EthanLog daemon using mapped severity levels. Key log points include engine initialization, GC timer installation, remote inspector startup, Essos context creation, application creation and termination, script download status, and WebSocket server events. --- From 483519643333fbe4d5f1451a005134c55717657d Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 31 Aug 2026 18:23:08 +0530 Subject: [PATCH 06/10] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 62b3c58..03dcf02 100644 --- a/docs/README.md +++ b/docs/README.md @@ -68,7 +68,7 @@ classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; rdkNativeScript is structured around a layered separation between engine management, context lifecycle, and application dispatch. The runtime is initialized once per process through `NativeJSRenderer`, which owns the `IJavaScriptEngine` instance and manages the map of active application contexts. Each application is represented by a numeric identifier mapped to a `JavaScriptContext` instance. The `JavaScriptContextBase` class provides engine-agnostic operations — file loading, script evaluation delegation, key event routing, and ThunderJS / RDK WebBridge code injection — while engine-specific implementations extend it for JSC or QuickJS. -Northbound, the component exposes its API through the Thunder plugin mechanism: clients issue a JSON-RPC `launchApplication` call to a cloned plugin instance. The server path, when enabled, accepts the same JSON command structure over a WebSocket connection on the port defined by `WS_SERVER_PORT`, enabling external tooling and testing frameworks to drive the runtime without a Thunder session. The `JSRuntimeServer` dispatches incoming messages to the same `NativeJSRenderer` methods used by the Thunder plugin path. Southbound, the component consumes the JavaScriptCore C API for script evaluation, GStreamer for media pipeline initialization, libcurl for script download from remote URLs, and the Essos API for Wayland compositor setup and keyboard event delivery. +Northbound, the component exposes its API through the Thunder plugin mechanism: clients issue a JSON-RPC `launchApplication` call to a cloned plugin instance. The server path, when enabled, accepts a similar command set over a WebSocket connection on the port defined by `WS_SERVER_PORT` using messages of the form `{ "method": "…", "params": { … } }` (module tokens are passed as `moduleSettings`). The `JSRuntimeServer` dispatches incoming messages to the same `NativeJSRenderer` methods used by the Thunder plugin path. Southbound, the component consumes the JavaScriptCore C API for script evaluation, GStreamer for media pipeline initialization, libcurl for script download from remote URLs, and the Essos API for Wayland compositor setup and keyboard event delivery. The design isolates per-application state (URL, JS context, module flags, performance metrics) inside `JavaScriptContext` and uses a shared `JSContextGroupRef` across all contexts in the process. This allows garbage collection to be coordinated globally through a periodic GLib timer while individual contexts can be released independently. The main GLib event loop processes both JSC internal events and timer callbacks on the main thread; applications are created and run from separate per-application threads that call into the renderer. From bfc4f0ab016e67464b5425c1bcaa14b2acfa4bec Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 14 Sep 2026 11:58:40 +0530 Subject: [PATCH 07/10] Address copilot review comments --- docs/README.md | 86 +++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/README.md b/docs/README.md index 03dcf02..8da51e4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -60,7 +60,7 @@ classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; - **Remote JavaScript Inspector**: Optionally starts a JSC remote inspector server to enable JavaScript debugging over a network connection, controlled via the `NATIVEJS_INSPECTOR_SERVER` environment variable. -- **Container Namespace Entry**: Supports running applications inside Linux containers by entering network, mount, IPC, and PID namespaces of a running container process, enabling script delivery over WebSocket to containerized runtime instances. +- **Container Namespace Entry**: Supports running applications inside Linux containers by entering network, mount, and IPC namespaces of a running container process, enabling script delivery over WebSocket to containerized runtime instances. --- @@ -117,15 +117,15 @@ graph TD ### Threading Model -- **Threading Architecture**: Multi-threaded with a main GLib event loop thread plus per-application worker threads and an optional WebSocket server thread. -- **Main Thread**: Runs the GLib main loop, which processes JSC internal callbacks, timer events (including the periodic GC timer), and uv event loop ticks. All JSC context creation and evaluation calls issued from the application threads re-enter the engine via the shared context group, with main-thread callbacks posted through `rtThreadQueue`. +- **Threading Architecture**: Multi-threaded with a renderer loop thread, request-caller threads, and an optional detached WebSocket server thread. +- **Renderer Loop**: Runs the GLib/uv processing and drains `gPendingRequests`; it creates contexts and evaluates application scripts on this thread. +- **Request Callers**: Standalone application threads (or IPC handlers) call `createApplication()` / `runApplication()` only to enqueue requests; they do not evaluate scripts. - **Worker Threads**: - - _Application thread_: One thread per launched application calls `renderer->createApplication()` and `renderer->runApplication()`. Evaluation of the script occurs on this thread; the result is surfaced when the script returns or the context is terminated. - _Console thread_: When developer console mode is enabled, a dedicated thread processes queued JavaScript snippets submitted interactively. - _WebSocket server thread_: When the server is enabled, a detached thread runs `WsServer::run()` to handle incoming WebSocket connections. - _Container namespace thread_: A temporary thread is spawned per `nsEnter` call to execute `setns` and perform the namespace-bound operation, then joins immediately. - **Synchronization**: `NativeJSRenderer` protects the context map with `mUserMutex`. The console state uses `isProcessing_cv` (condition variable + mutex) for producer/consumer coordination of queued scripts. `JSRuntimeServer` protects the connection set with `mDataMutex`. `JSRuntimeClient` uses `mResponseMutex` and `mResponseCondition` with a 5-second wait-for-response timeout. -- **Async / Event Dispatch**: Key events from Essos are dispatched synchronously into the registered `JavaScriptKeyListener` (the active context). Timer callbacks and deferred JS execution are scheduled through the GLib main loop rather than blocking caller threads. +- **Async / Event Dispatch**: Essos key events are dispatched synchronously to the single listener stored by `EssosInstance` (constructing another context replaces that listener). Timer callbacks and deferred JS execution are scheduled through the GLib main loop rather than blocking caller threads. ### RDKE/RDKV Platform and Integration Requirements @@ -154,7 +154,7 @@ graph TD **Population Mechanisms:** -- **Via Thunder JSON-RPC or WebSocket command**: The `options` parameter of `launchApplication` is a comma-separated string of token names (e.g., `"player,xhr,ws"`). `ModuleSettings::fromString()` parses this string and sets the corresponding boolean flags. +- **Via Thunder JSON-RPC or WebSocket command**: Thunder JSON-RPC uses the `options` parameter, while the WebSocket `launchApplication` command uses `moduleSettings`; both carry a comma-separated string of token names (e.g., `"player,xhr,ws"`). `ModuleSettings::fromString()` parses the string and sets the corresponding boolean flags. - **Via standalone launcher (jsruntime-launcher)**: The launcher reads an `app.config` JSON file at `/package/app.config` and maps `features` array entries (e.g., `{"name": "player", "enable": true}`) to command-line flags (`--enablePlayer`, `--enableXHR`, etc.), which are then parsed into `ModuleSettings` fields before the application context is created. All flags default to `false`; only tokens present in the options string activate the corresponding module. `minijsdom` and `jsdom` are mutually exclusive — `minijsdom` takes precedence when both tokens appear. @@ -181,7 +181,7 @@ sequenceDiagram NR->>Essos: EssosInstance.initialize useWayland Essos-->>NR: Essos context ready NR->>JSE: new JavaScriptEngine and initialize - JSE->>GST: gst_init if player enabled + JSE->>GST: gst_init when player support is compiled and NATIVEJS_GST_START_DISABLE is unset JSE->>JSE: WTF.initializeMainThread JSE->>JSE: g_main_loop_new and install GC timer Note over JSE: Remote inspector started if NATIVEJS_INSPECTOR_SERVER set @@ -267,9 +267,9 @@ sequenceDiagram | `JavaScriptEngine` | Concrete JSC engine implementation. Initializes the WTF main thread, GLib event loop, GStreamer pipeline subsystem, remote inspector server, and the periodic garbage collection timer. Implements `IJavaScriptEngine`. | `src/jsc/JavaScriptEngine.cpp`, `include/jsc/JavaScriptEngine.h` | | `JavaScriptContext` | Per-application JSC global context. Registers all enabled module bindings (setTimeout, XHR, WebSocket, HTTP, Fetch, JSDOM, crypto, player). Tracks performance metrics (context creation time, execution time, playback start time) and network metrics via `NetworkMetricsListener`. Implements `IJavaScriptContext`. | `src/jsc/JavaScriptContext.cpp`, `include/jsc/JavaScriptContext.h` | | `JavaScriptContextBase` | Engine-agnostic base class for JavaScript contexts. Implements file loading, `runScript`, `runFile`, key event routing to the active context, ThunderJS and RDK WebBridge code injection, and module path resolution. | `src/JavaScriptContextBase.cpp`, `include/JavaScriptContextBase.h` | -| `JSRuntimeServer` | WebSocket server (singleton) that listens on a configurable port and dispatches JSON-encoded `launchApplication`, `createApplication`, `runApplication`, `runJavaScript`, and `terminateApplication` commands to `NativeJSRenderer`. Uses websocketpp with Asio transport. | `src/JSRuntimeServer.cpp`, `include/JSRuntimeServer.h` | +| `JSRuntimeServer` | WebSocket server (singleton) that listens on a configurable port and dispatches JSON-encoded `launchApplication`, `createApplication`, `runApplication`, `runJavaScript`, and `destroyApplication` commands to `NativeJSRenderer`. Uses websocketpp with Asio transport. | `src/JSRuntimeServer.cpp`, `include/JSRuntimeServer.h` | | `JSRuntimeClient` | WebSocket client (singleton) that connects to a `JSRuntimeServer` instance and provides a synchronous `sendCommand` interface with a 5-second response timeout. Used by `JSRuntimeContainer` to relay launch commands into a container. | `src/JSRuntimeClient.cpp`, `include/JSRuntimeClient.h` | -| `JSRuntimeContainer` | Provides utilities for entering Linux namespaces (network, mount, IPC, PID) of a containerized process by resolving the container PID from the cgroup filesystem and calling `setns` on a temporary thread. Also builds and dispatches WebSocket launch messages to the in-container server. | `src/JSRuntimeContainer.cpp`, `include/JSRuntimeContainer.h` | +| `JSRuntimeContainer` | Provides utilities for entering Linux namespaces (network, mount, IPC) of a containerized process by resolving the container PID from the cgroup filesystem and calling `setns` on a temporary thread. Also builds and dispatches WebSocket launch messages to the in-container server. | `src/JSRuntimeContainer.cpp`, `include/JSRuntimeContainer.h` | | `EssosInstance` | Singleton wrapper around the Essos compositor abstraction API. Initializes an Essos context against the active Wayland display and translates raw Wayland key events into `JavaScriptKeyDetails` structures that are forwarded to the registered `JavaScriptKeyListener`. | `src/EssosInstance.cpp`, `include/EssosInstance.h` | | `ModuleSettings` | Plain data structure holding boolean flags for each optional JavaScript module. Populated either from command-line flags in standalone mode or by parsing a comma-separated options string passed to `launchApplication`. | `src/ModuleSettings.cpp`, `include/ModuleSettings.h` | | `NativeJSLogger` | Component-level logger with five severity levels (DEBUG, INFO, WARN, ERROR, FATAL). Level is set via the `NATIVEJS_LOG_LEVEL` environment variable at startup. Supports output to either stdout or EthanLog when the `ETHAN_LOGGING_PIPE` environment variable is present. | `src/NativeJSLogger.cpp`, `include/NativeJSLogger.h` | @@ -281,24 +281,24 @@ sequenceDiagram ### Interaction Matrix -| Target Component / Layer | Interaction Purpose | Key APIs / Topics | -| ------------------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| **Plugins** | | | -| `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | -| **HAL** | | | -| Essos | Wayland display initialization and keyboard input routing | `EssCtxCreate`, `EssCtxSetKeyboardListener`, `EssCtxStart` | -| GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | -| AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | -| libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | -| **External Systems** | | | -| WebSocket Server (self) | External tools and container clients send application control commands | WebSocket JSON messages: `launchApplication`, `createApplication`, `terminateApplication` | -| Remote Inspector | JavaScript debugger connection over network | `JSRemoteInspectorStart()`, env `NATIVEJS_INSPECTOR_SERVER` | +| Target Component / Layer | Interaction Purpose | Key APIs / Topics | +| ------------------------ | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | +| **Plugins** | | | +| `Thunder` | Plugin activation, JSON-RPC method dispatch, plugin cloning | `Controller.1.clone`, `Controller.1.activate`, `launchApplication` | +| **HAL** | | | +| Essos | Wayland display initialization and keyboard input routing | `EssContextCreate`, `EssContextSetKeyListener`, `EssContextStart` | +| GStreamer | Media pipeline subsystem initialization required for AAMP playback | `gst_init()` | +| AAMP JS Bindings | Media playback control exposed as `AAMPMediaPlayer` in JavaScript | `AAMPPlayer_LoadJS()`, `AAMPPlayer_UnloadJS()` (dynamic: `libaampjsbindings.so`) | +| libcurl | Remote script file download by URL before evaluation | `curl_easy_perform`, write callbacks | +| **External Systems** | | | +| WebSocket Server (self) | External tools and container clients send application control commands | WebSocket JSON messages: `launchApplication`, `createApplication`, `destroyApplication` | +| Remote Inspector | JavaScript debugger connection over network | `JSRemoteInspectorStart()`, env `NATIVEJS_INSPECTOR_SERVER` | ### Events Published -| Event Name | Topic | Trigger Condition | Subscriber Components | -| ------------------- | ----------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- | -| Key press / release | Internal `JavaScriptKeyListener` callback | Wayland key event received by EssosInstance | Active `JavaScriptContextBase` (processes key event in JS engine) | +| Event Name | Topic | Trigger Condition | Subscriber Components | +| ------------------- | ----------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------- | +| Key press / release | Internal `JavaScriptKeyListener` callback | Wayland key event received by EssosInstance | `JavaScriptContextBase` registered as the current key listener (processes key event in JS engine) | ### IPC Flow Patterns @@ -312,12 +312,12 @@ sequenceDiagram participant CTX as JavaScriptContext ExtTool->>SRV: WebSocket connect (WS_SERVER_PORT) - ExtTool->>SRV: JSON: {"method": "launchApplication", "params": {"url": "...", "options": "player,xhr"}} + ExtTool->>SRV: JSON: {"method": "launchApplication", "params": {"url": "...", "moduleSettings": "player,xhr"}} SRV->>NR: createApplication(moduleSettings) SRV->>NR: runApplication(id, url) NR->>CTX: Script execution CTX-->>NR: Done - SRV-->>ExtTool: JSON response {success, id} + SRV-->>ExtTool: JSON response {"result":"ID : "} ``` --- @@ -328,10 +328,10 @@ sequenceDiagram | API | Purpose | Implementation File | | ------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------- | -| `EssCtxCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | -| `EssCtxSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | -| `EssCtxSetKeyboardListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | -| `EssCtxStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | +| `EssContextCreate()` | Creates an Essos compositor context | `src/EssosInstance.cpp` | +| `EssContextSetTerminateListener()` | Registers a termination callback with the compositor | `src/EssosInstance.cpp` | +| `EssContextSetKeyListener()` | Registers a keyboard input callback for key press and release events | `src/EssosInstance.cpp` | +| `EssContextStart()` | Starts the Essos event loop, connecting to the Wayland display | `src/EssosInstance.cpp` | | `gst_init()` | Initializes the GStreamer framework before any pipeline creation | `src/jsc/JavaScriptEngine.cpp` | | `AAMPPlayer_LoadJS()` | Loads AAMP JS bindings into a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | | `AAMPPlayer_UnloadJS()` | Unloads AAMP JS bindings from a JSC global context (static mode) | `src/jsc/JavaScriptContext.cpp` | @@ -348,7 +348,7 @@ sequenceDiagram - **Event Processing**: Keyboard events from Essos flow through `EssosInstance` static callbacks, which call `onKeyPress` / `onKeyRelease` on the registered `JavaScriptKeyListener`. `JavaScriptContextBase` implements that listener and forwards events to the engine-specific `processKeyEvent()` implementation. JSC contexts then inject a synthetic DOM key event object into the executing script context. -- **Error Handling Strategy**: Logger calls at WARN and ERROR levels mark failure points. When a script file cannot be loaded, the failure is logged and the operation returns. When the AAMP dynamic library is unavailable, the failure is logged and context creation proceeds with the remaining enabled bindings. libcurl download failures are logged and result in an empty script evaluation. WebSocket send failures in `JSRuntimeServer` are caught and logged, preserving the active connection. +- **Error Handling Strategy**: Logger calls at WARN and ERROR levels mark failure points. When a script file cannot be loaded, the failure is logged and the operation returns. When the AAMP dynamic library is unavailable, the failure is logged and context creation proceeds with the remaining enabled bindings. libcurl download failures are logged and abort the application run. WebSocket send failures in `JSRuntimeServer` are caught and logged, preserving the active connection. - **Logging & Diagnostics**: Console logs are emitted as `[LEVEL] JsRuntime Thread-: `; when `ETHAN_LOGGING_PIPE` is set (EthanLog enabled), the message is prefixed with `JSRuntime [Thread-]`. The log level is controlled by the `NATIVEJS_LOG_LEVEL` environment variable (DEBUG, INFO, WARN, ERROR, FATAL); the default level is INFO. When `ETHAN_LOGGING_PIPE` is set, output is redirected to the EthanLog daemon using mapped severity levels. Key log points include engine initialization, GC timer installation, remote inspector startup, Essos context creation, application creation and termination, script download status, and WebSocket server events. @@ -358,18 +358,18 @@ sequenceDiagram ### Key Configuration Parameters -| Parameter | Type | Default | Description | -| ----------------------------- | -------------- | --------------- | -------------------------------------------------------------------------------------------------------------- | -| `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | -| `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | -| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | -| `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | -| `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp/nativejsEmbedThunder` sentinel file. | -| `NATIVEJS_ENABLE_WEBSOCKET_SERVER` | string (env) | _(not set)_ | When set, enables the WebSocket server. Equivalent to creating the `/tmp/nativejsEnableWebSocketServer` sentinel file. | -| `/tmp/nativejsRdkWebBridge` | file (sentinel)| _(not present)_ | When present, enables rdk WebBridge injection into all contexts. | -| `WAYLAND_DISPLAY` | string (env) | _(not set)_ | Set automatically from the `--display` argument to direct the runtime to a specific Wayland compositor socket. | -| `WS_SERVER_PORT` | int (build) | `5000` | WebSocket server listen port. Defined at build time via `-DWS_SERVER_PORT=5000`. | -| `NATIVEJS_DUMP_NETWORKMETRIC` | string (env) | _(not set)_ | When set, collects network metrics and stores the output to a file in `/tmp`. | +| Parameter | Type | Default | Description | +| ---------------------------------- | --------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | +| `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | +| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | +| `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | +| `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp/nativejsEmbedThunder` sentinel file. | +| `NATIVEJS_ENABLE_WEBSOCKET_SERVER` | string (env) | _(not set)_ | When set, or when the `/tmp/nativejsEnableWebSocketServer` sentinel exists, enables the JavaScript `webSocketServer` binding in contexts (when built with `ENABLE_WEBSOCKET_SERVER`). It does not start the external `JSRuntimeServer`, which is started with the standalone `--server` option. | +| `/tmp/nativejsRdkWebBridge` | file (sentinel) | _(not present)_ | When present, enables RDK WebBridge injection into all contexts. | +| `WAYLAND_DISPLAY` | string (env) | _(not set)_ | Set automatically from the `--display` argument to direct the runtime to a specific Wayland compositor socket. | +| `WS_SERVER_PORT` | int (build) | `5000` | WebSocket server listen port. Defined at build time via `-DWS_SERVER_PORT=5000`. | +| `NATIVEJS_DUMP_NETWORKMETRIC` | string (env) | _(not set)_ | When set, collects network metrics and stores the output to a file in `/tmp`. | ### Runtime Configuration From 0b51e912072fe5240603cd99036e57a419a2c1f9 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 14 Sep 2026 12:29:20 +0530 Subject: [PATCH 08/10] Apply batched suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 8da51e4..98cabdd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,7 +46,7 @@ classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; **Key Features & Responsibilities:** -- **Multi-context JavaScript Execution**: Hosts multiple independent JavaScript application contexts within a single process. Each application receives its own JSC global context with its own module bindings, allowing widgets and lightweight apps to run concurrently without interference. +- **Multi-context JavaScript Execution**: Hosts multiple JavaScript application contexts within a single process, each with its own JSC global context and module bindings. Application requests are evaluated serially by the renderer loop, and shared process resources are not isolated per context. - **Engine Abstraction**: Decouples the application runtime from the underlying JavaScript engine through the `IJavaScriptEngine` and `IJavaScriptContext` interfaces. The primary engine is JavaScriptCore (JSC); the build system also supports QuickJS as an alternate engine. @@ -54,7 +54,7 @@ classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; - **AAMP Media Player Integration**: Exposes `AAMPMediaPlayer` as a JavaScript global when the player module is enabled. AAMP bindings are deployed as a DAC (Downloadable Application Container) module, decoupling the player library from the runtime binary. -- **WebSocket Server and Client IPC**: Provides an optional WebSocket server (on the port defined by `WS_SERVER_PORT`) that accepts JSON-encoded commands to launch, run, and terminate applications remotely. A corresponding client is also provided for applications that need to connect to the server. +- **WebSocket Server and Client IPC**: Provides an optional WebSocket server (on the port defined by `WS_SERVER_PORT`) that accepts unauthenticated JSON-encoded commands to launch, run, execute JavaScript in, and terminate applications remotely. A corresponding client is also provided; the endpoint must be restricted to a trusted network. - **Wayland Display and Input Handling**: Integrates with the Essos compositor abstraction layer to set up a Wayland display surface and route keyboard input events from the compositor into the active JavaScript context. @@ -155,7 +155,7 @@ graph TD **Population Mechanisms:** - **Via Thunder JSON-RPC or WebSocket command**: Thunder JSON-RPC uses the `options` parameter, while the WebSocket `launchApplication` command uses `moduleSettings`; both carry a comma-separated string of token names (e.g., `"player,xhr,ws"`). `ModuleSettings::fromString()` parses the string and sets the corresponding boolean flags. -- **Via standalone launcher (jsruntime-launcher)**: The launcher reads an `app.config` JSON file at `/package/app.config` and maps `features` array entries (e.g., `{"name": "player", "enable": true}`) to command-line flags (`--enablePlayer`, `--enableXHR`, etc.), which are then parsed into `ModuleSettings` fields before the application context is created. +- **Via the container launcher (`JSRuntimeContainer`)**: The launcher reads each app’s `app.config`, converts enabled `features` entries directly to a comma-separated module-settings string, and sends a WebSocket `launchApplication` command. The standalone `jsruntime_app` uses `--enable...` command-line flags instead. All flags default to `false`; only tokens present in the options string activate the corresponding module. `minijsdom` and `jsdom` are mutually exclusive — `minijsdom` takes precedence when both tokens appear. @@ -247,7 +247,7 @@ sequenceDiagram NR->>CTX: new JavaScriptContext(moduleSettings, url, engine) Note over CTX: Register bindings for enabled modules\n(XHR, WebSocket, Player, Fetch, JSDOM…) alt Player module enabled - CTX->>AAMP: loadAAMPJSBindingsLib() / AAMPPlayer_LoadJS(context) + CTX->>AAMP: Static AAMPPlayer_LoadJS(context), or dynamic dlopen(libaampjsbindings.so) / aamp_LoadJSController(context) end NR->>CURL: downloadFile(url) [if remote URL] CURL-->>NR: Script content From 6d186559fd4adbfb7cc0655cb7699cd7f4a476e4 Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 14 Sep 2026 13:04:28 +0530 Subject: [PATCH 09/10] Apply batched suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 98cabdd..956ca76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -58,7 +58,7 @@ classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px; - **Wayland Display and Input Handling**: Integrates with the Essos compositor abstraction layer to set up a Wayland display surface and route keyboard input events from the compositor into the active JavaScript context. -- **Remote JavaScript Inspector**: Optionally starts a JSC remote inspector server to enable JavaScript debugging over a network connection, controlled via the `NATIVEJS_INSPECTOR_SERVER` environment variable. +- **Remote JavaScript Inspector**: Optionally starts a JSC remote inspector server to enable JavaScript debugging over a network connection, controlled via the `NATIVEJS_INSPECTOR_SERVER` environment variable. The endpoint is unauthenticated and should be restricted to a trusted network. - **Container Namespace Entry**: Supports running applications inside Linux containers by entering network, mount, and IPC namespaces of a running container process, enabling script delivery over WebSocket to containerized runtime instances. @@ -268,7 +268,7 @@ sequenceDiagram | `JavaScriptContext` | Per-application JSC global context. Registers all enabled module bindings (setTimeout, XHR, WebSocket, HTTP, Fetch, JSDOM, crypto, player). Tracks performance metrics (context creation time, execution time, playback start time) and network metrics via `NetworkMetricsListener`. Implements `IJavaScriptContext`. | `src/jsc/JavaScriptContext.cpp`, `include/jsc/JavaScriptContext.h` | | `JavaScriptContextBase` | Engine-agnostic base class for JavaScript contexts. Implements file loading, `runScript`, `runFile`, key event routing to the active context, ThunderJS and RDK WebBridge code injection, and module path resolution. | `src/JavaScriptContextBase.cpp`, `include/JavaScriptContextBase.h` | | `JSRuntimeServer` | WebSocket server (singleton) that listens on a configurable port and dispatches JSON-encoded `launchApplication`, `createApplication`, `runApplication`, `runJavaScript`, and `destroyApplication` commands to `NativeJSRenderer`. Uses websocketpp with Asio transport. | `src/JSRuntimeServer.cpp`, `include/JSRuntimeServer.h` | -| `JSRuntimeClient` | WebSocket client (singleton) that connects to a `JSRuntimeServer` instance and provides a synchronous `sendCommand` interface with a 5-second response timeout. Used by `JSRuntimeContainer` to relay launch commands into a container. | `src/JSRuntimeClient.cpp`, `include/JSRuntimeClient.h` | +| `JSRuntimeClient` | WebSocket client (singleton) that connects to a `JSRuntimeServer` instance and provides a synchronous `sendCommand` interface with a 5-second response timeout. Used by the standalone client executable to send commands to a runtime server. | `src/JSRuntimeClient.cpp`, `include/JSRuntimeClient.h` | | `JSRuntimeContainer` | Provides utilities for entering Linux namespaces (network, mount, IPC) of a containerized process by resolving the container PID from the cgroup filesystem and calling `setns` on a temporary thread. Also builds and dispatches WebSocket launch messages to the in-container server. | `src/JSRuntimeContainer.cpp`, `include/JSRuntimeContainer.h` | | `EssosInstance` | Singleton wrapper around the Essos compositor abstraction API. Initializes an Essos context against the active Wayland display and translates raw Wayland key events into `JavaScriptKeyDetails` structures that are forwarded to the registered `JavaScriptKeyListener`. | `src/EssosInstance.cpp`, `include/EssosInstance.h` | | `ModuleSettings` | Plain data structure holding boolean flags for each optional JavaScript module. Populated either from command-line flags in standalone mode or by parsing a comma-separated options string passed to `launchApplication`. | `src/ModuleSettings.cpp`, `include/ModuleSettings.h` | From 83e331cc9ba383548e73c3cd9e50e1cf339a80ed Mon Sep 17 00:00:00 2001 From: gourivarma3 Date: Mon, 14 Sep 2026 14:06:22 +0530 Subject: [PATCH 10/10] Apply batched suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 956ca76..6235741 100644 --- a/docs/README.md +++ b/docs/README.md @@ -362,7 +362,7 @@ sequenceDiagram | ---------------------------------- | --------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `NATIVEJS_LOG_LEVEL` | string (env) | `INFO` | Sets the logging verbosity. Accepted values: `debug`, `info`, `warn`, `error`, `fatal`. | | `NATIVEJS_GC_INTERVAL` | float (env) | `60000` | Garbage collection timer interval in milliseconds. Controls how frequently the JSC GC runs. | -| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the remote JavaScript inspector. Format: `host:port` (e.g., `0.0.0.0:9226`). | +| `NATIVEJS_INSPECTOR_SERVER` | string (env) | _(not set)_ | Activates the custom remote JavaScript inspector only when built with `REMOTE_INSPECTOR_ENABLE`. The value supplies a port in `host:port` form, but the server listens on all interfaces; restrict access to a trusted network. | | `NATIVEJS_GST_START_DISABLE` | string (env) | _(not set)_ | When set to any value, suppresses `gst_init()` during engine initialization. | | `NATIVEJS_EMBED_THUNDERJS` | string (env) | _(not set)_ | When set, enables ThunderJS injection into all contexts. Equivalent to creating the `/tmp/nativejsEmbedThunder` sentinel file. | | `NATIVEJS_ENABLE_WEBSOCKET_SERVER` | string (env) | _(not set)_ | When set, or when the `/tmp/nativejsEnableWebSocketServer` sentinel exists, enables the JavaScript `webSocketServer` binding in contexts (when built with `ENABLE_WEBSOCKET_SERVER`). It does not start the external `JSRuntimeServer`, which is started with the standalone `--server` option. |