From de253bf5fcbd693a7ac5b4d167cb6e398dd66968 Mon Sep 17 00:00:00 2001 From: gsarng517_comcast Date: Mon, 16 Feb 2026 15:33:34 +0530 Subject: [PATCH 1/4] RDKEMW-13250: Memory Metrics analysis for VIPA Reason for change: Added minified jsdom for widget Test Procedure: build should be successful Risk: low Priority: P2 --- include/ModuleSettings.h | 1 + include/NativeJSRenderer.h | 3 +- src/ModuleSettings.cpp | 13 ++- src/NativeJSRenderer.cpp | 5 +- src/jsc/JavaScriptContext.cpp | 6 + src/jsc/modules/minified_linkedjsdom.js | 141 ++++++++++++++++++++++++ src/jsruntime.cpp | 4 + 7 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 src/jsc/modules/minified_linkedjsdom.js diff --git a/include/ModuleSettings.h b/include/ModuleSettings.h index a255182..ba43d2e 100644 --- a/include/ModuleSettings.h +++ b/include/ModuleSettings.h @@ -34,5 +34,6 @@ struct ModuleSettings bool enableJSDOM; bool enableWindow; bool enablePlayer; + bool enableMiniJSDOM; }; #endif diff --git a/include/NativeJSRenderer.h b/include/NativeJSRenderer.h index 6fc061e..ee9f629 100644 --- a/include/NativeJSRenderer.h +++ b/include/NativeJSRenderer.h @@ -95,7 +95,7 @@ namespace JsRuntime { struct ApplicationRequest { - ApplicationRequest(uint32_t id, RequestType requestType, std::string url="", bool enableHttp=false, bool enableXHR=false, bool enableWebSocket=false, bool enableWebSocketEnhanced=false, bool enableFetch=false, bool enableJSDOM=false, bool enableWindow=false, bool enablePlayer=false, std::string userAgent=""): mId(id), mRequestType(requestType), mUrl(url), mEnableHttp(enableHttp), mEnableXHR(enableXHR), mEnableWebSocket(enableWebSocket), mEnableWebSocketEnhanced(enableWebSocketEnhanced), mEnableFetch(enableFetch), mEnableJSDOM(enableJSDOM), mEnableWindow(enableWindow), mEnablePlayer(enablePlayer), mUserAgent(userAgent) + ApplicationRequest(uint32_t id, RequestType requestType, std::string url="", bool enableHttp=false, bool enableXHR=false, bool enableWebSocket=false, bool enableWebSocketEnhanced=false, bool enableFetch=false, bool enableJSDOM=false, bool enableWindow=false, bool enablePlayer=false, bool enableMiniJSDOM=false, std::string userAgent=""): mId(id), mRequestType(requestType), mUrl(url), mEnableHttp(enableHttp), mEnableXHR(enableXHR), mEnableWebSocket(enableWebSocket), mEnableWebSocketEnhanced(enableWebSocketEnhanced), mEnableFetch(enableFetch), mEnableJSDOM(enableJSDOM), mEnableWindow(enableWindow), mEnablePlayer(enablePlayer), mEnableMiniJSDOM(enableMiniJSDOM), mUserAgent(userAgent) { } uint32_t mId; @@ -109,6 +109,7 @@ namespace JsRuntime { bool mEnableJSDOM; bool mEnableWindow; bool mEnablePlayer; + bool mEnableMiniJSDOM; std::string mUserAgent; }; diff --git a/src/ModuleSettings.cpp b/src/ModuleSettings.cpp index 32f2586..5dd762e 100644 --- a/src/ModuleSettings.cpp +++ b/src/ModuleSettings.cpp @@ -19,7 +19,7 @@ #include ModuleSettings::ModuleSettings(): enableHttp(false), enableXHR(false), enableWebSocket(false), enableWebSocketEnhanced(false) - , enableFetch(false), enableJSDOM(false), enableWindow(false), enablePlayer(false) + , enableFetch(false), enableJSDOM(false), enableWindow(false), enablePlayer(false), enableMiniJSDOM(false) { } @@ -30,7 +30,8 @@ ModuleSettings::ModuleSettings(ModuleSettings& settings): enableHttp(settings.en enableFetch(settings.enableFetch), enableJSDOM(settings.enableJSDOM), enableWindow(settings.enableWindow), - enablePlayer(settings.enablePlayer) + enablePlayer(settings.enablePlayer), + enableMiniJSDOM(settings.enableMiniJSDOM) { } @@ -56,7 +57,11 @@ void ModuleSettings::fromString(std::string& options) { enableFetch = true; } - if (options.find("jsdom") != std::string::npos) + if (options.find("minijsdom") != std::string::npos) + { + enableMiniJSDOM = true; + } + else if (options.find("jsdom") != std::string::npos) { enableJSDOM = true; } @@ -67,5 +72,5 @@ void ModuleSettings::fromString(std::string& options) if (options.find("player") != std::string::npos) { enablePlayer = true; - } + } } diff --git a/src/NativeJSRenderer.cpp b/src/NativeJSRenderer.cpp index 4e98f41..ca370d8 100644 --- a/src/NativeJSRenderer.cpp +++ b/src/NativeJSRenderer.cpp @@ -235,7 +235,7 @@ uint32_t NativeJSRenderer::createApplication(ModuleSettings& moduleSettings, st uint32_t id=0; mUserMutex.lock(); id = createApplicationIdentifier(); - ApplicationRequest request(id, CREATE, "", moduleSettings.enableHttp, moduleSettings.enableXHR, moduleSettings.enableWebSocket, moduleSettings.enableWebSocketEnhanced, moduleSettings.enableFetch, moduleSettings.enableJSDOM, moduleSettings.enableWindow, moduleSettings.enablePlayer, userAgent); + ApplicationRequest request(id, CREATE, "", moduleSettings.enableHttp, moduleSettings.enableXHR, moduleSettings.enableWebSocket, moduleSettings.enableWebSocketEnhanced, moduleSettings.enableFetch, moduleSettings.enableJSDOM, moduleSettings.enableWindow, moduleSettings.enablePlayer, moduleSettings.enableMiniJSDOM, userAgent); gPendingRequests.push_back(request); mUserMutex.unlock(); return id; @@ -305,6 +305,7 @@ void NativeJSRenderer::createApplicationInternal(ApplicationRequest& appRequest) settings.enableJSDOM = appRequest.mEnableJSDOM; settings.enableWindow = appRequest.mEnableWindow; settings.enablePlayer = appRequest.mEnablePlayer; + settings.enableMiniJSDOM = appRequest.mEnableMiniJSDOM; uint32_t id= appRequest.mId; std::string userAgent = appRequest.mUserAgent; JavaScriptContextFeatures features(mEmbedThunderJS, mEmbedRdkWebBridge, mEnableWebSocketServer, settings); @@ -509,7 +510,7 @@ void NativeJSRenderer::run() ModuleSettings settings; uint32_t id = createApplicationIdentifier(); settings.enableJSDOM = mEnableTestFileDOMSupport; - ApplicationRequest appRequest(id, RUN, mTestFileName, settings.enableHttp, settings.enableXHR, settings.enableWebSocket, settings.enableWebSocketEnhanced, settings.enableFetch, settings.enableJSDOM, settings.enableWindow, settings.enablePlayer); + ApplicationRequest appRequest(id, RUN, mTestFileName, settings.enableHttp, settings.enableXHR, settings.enableWebSocket, settings.enableWebSocketEnhanced, settings.enableFetch, settings.enableJSDOM, settings.enableWindow, settings.enablePlayer, settings.enableMiniJSDOM); mUserMutex.lock(); NativeJSRenderer::createApplicationInternal(appRequest); NativeJSRenderer::runApplicationInternal(appRequest); diff --git a/src/jsc/JavaScriptContext.cpp b/src/jsc/JavaScriptContext.cpp index 3dd3389..c70e11a 100644 --- a/src/jsc/JavaScriptContext.cpp +++ b/src/jsc/JavaScriptContext.cpp @@ -466,6 +466,12 @@ if (mModuleSettings.enablePlayer) runFile("linkedjsdomwrapper.js", nullptr/*, true*/); runFile("windowwrapper.js", nullptr/*, true*/); runFile("url.js", nullptr/*, true*/); + + } + else if (mModuleSettings.enableMiniJSDOM) + { + runFile("minified_linkedjsdom.js", nullptr/*, true*/); + runFile("url.js", nullptr/*, true*/); if(getenv("FIREBOLT_ENDPOINT")!=NULL) { auto FireboltEndpoint = std::string(getenv("FIREBOLT_ENDPOINT")); diff --git a/src/jsc/modules/minified_linkedjsdom.js b/src/jsc/modules/minified_linkedjsdom.js new file mode 100644 index 0000000..cb9d064 --- /dev/null +++ b/src/jsc/modules/minified_linkedjsdom.js @@ -0,0 +1,141 @@ +var document = { + createElement: function() { + return { + style: {}, + setAttribute: function() {}, + getAttribute: function() { return null; }, + hasAttribute: function() { return false; }, + appendChild: function(c) { return c; }, + removeChild: function(c) { return c; }, + addEventListener: function() {}, + getBoundingClientRect: function() { return {top:0,left:0,right:0,bottom:0,width:0,height:0,x:0,y:0}; } + }; + }, + createEvent: function(type) { + return { + initEvent: function(t, bubbles, cancelable) { this.type = t; this.bubbles = bubbles; this.cancelable = cancelable; }, + type: '', + bubbles: false, + cancelable: false, + preventDefault: function() {} + }; + }, + getElementById: function(id) { return id === 'videoDiv' ? this.createElement() : null; }, + querySelector: function(s) { return s === '#videoDiv' ? this.getElementById('videoDiv') : null; }, + body: { appendChild: function(c) { return c; } }, + head: { appendChild: function(c) { return c; } } +}; + +function Event(t) { this.type = t; } +Event.prototype.preventDefault = function() {}; + +function DOMParser() {} +DOMParser.prototype.parseFromString = function() { return document; }; + +function Blob(parts, options) { this.size = 0; this.type = (options && options.type) || ''; } +Blob.prototype.slice = function() { return new Blob([], {}); }; + +// AbortController for fetch API +function AbortController() { + this.signal = { aborted: false, addEventListener: function() {} }; +} +AbortController.prototype.abort = function() { + this.signal.aborted = true; +}; + +// Minimal fetch stub +function fetch(url, options) { + return new Promise(function(resolve, reject) { + if (options && options.signal && options.signal.aborted) { + var error = new Error('Aborted'); + error.name = 'AbortError'; + reject(error); + return; + } + // Stub response + resolve({ + ok: true, + status: 200, + json: function() { return Promise.resolve({}); }, + text: function() { return Promise.resolve(''); }, + blob: function() { return Promise.resolve(new Blob([], {})); } + }); + }); +} + +// Wrap timer functions to ensure .apply() works +var _setTimeout = setTimeout; +var _setInterval = setInterval; +var _clearTimeout = clearTimeout; +var _clearInterval = clearInterval; + +function wrappedSetTimeout(fn, delay) { + var args = Array.prototype.slice.call(arguments, 2); + return _setTimeout(function() { fn.apply(null, args); }, delay); +} +wrappedSetTimeout.apply = function(thisArg, argArray) { + if (!argArray || argArray.length === 0) return _setTimeout(); + if (argArray.length === 1) return _setTimeout(argArray[0]); + if (argArray.length === 2) return _setTimeout(argArray[0], argArray[1]); + var args = Array.prototype.slice.call(argArray, 2); + return _setTimeout(function() { argArray[0].apply(null, args); }, argArray[1]); +}; + +function wrappedSetInterval(fn, delay) { + var args = Array.prototype.slice.call(arguments, 2); + return _setInterval(function() { fn.apply(null, args); }, delay); +} +wrappedSetInterval.apply = function(thisArg, argArray) { + if (!argArray || argArray.length === 0) return _setInterval(); + if (argArray.length === 1) return _setInterval(argArray[0]); + if (argArray.length === 2) return _setInterval(argArray[0], argArray[1]); + var args = Array.prototype.slice.call(argArray, 2); + return _setInterval(function() { argArray[0].apply(null, args); }, argArray[1]); +}; + +function wrappedClearTimeout(id) { return _clearTimeout(id); } +wrappedClearTimeout.apply = function(thisArg, argArray) { + return _clearTimeout(argArray ? argArray[0] : undefined); +}; + +function wrappedClearInterval(id) { return _clearInterval(id); } +wrappedClearInterval.apply = function(thisArg, argArray) { + return _clearInterval(argArray ? argArray[0] : undefined); +}; + +var window = { + document: document, + location: {href:'',host:'127.0.0.1',hostname:'127.0.0.1'}, + navigator: {userAgent:'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36',platform:'Linux'}, + console: console, + setTimeout: wrappedSetTimeout, + setInterval: wrappedSetInterval, + clearTimeout: wrappedClearTimeout, + clearInterval: wrappedClearInterval, + addEventListener: function() {}, + Event: Event, + DOMParser: DOMParser, + Blob: Blob, + AbortController: AbortController, + fetch: fetch, + Promise: Promise +}; + +window.window = window; +window.self = window; +var navigator = window.navigator; +var location = window.location; +window.top = window; +var tv = window.tv = {}; +var DOMParser = window.DOMParser; +var Event = window.Event; +var Blob = window.Blob; +var AbortController = window.AbortController; +var fetch = window.fetch; +var Promise = window.Promise; +var top = window; +var setTimeout = wrappedSetTimeout; +var setInterval = wrappedSetInterval; +var clearTimeout = wrappedClearTimeout; +var clearInterval = wrappedClearInterval; +var LinkedJSDOMLib = {parseHTML: function() { return {window:window,document:document,defaultView:window}; }}; diff --git a/src/jsruntime.cpp b/src/jsruntime.cpp index cdfe54e..f0e4bf9 100644 --- a/src/jsruntime.cpp +++ b/src/jsruntime.cpp @@ -128,6 +128,10 @@ int main(int argc, char* argv[]) { moduleSettings.enablePlayer = true; } + else if (strcmp(argv[i], "--enableMiniJSDOM") == 0) + { + moduleSettings.enableMiniJSDOM = true; + } else if (strcmp(argv[i], "--console") == 0) { consoleMode = true; From c28551fd63d12bc6eb27e1bfd5f0f25726344160 Mon Sep 17 00:00:00 2001 From: Sidhanth B H Date: Thu, 19 Feb 2026 15:55:09 +0530 Subject: [PATCH 2/4] RDKEMW-13657: Plugin Feature fails on Xione-UK Reason for change: Resolving the plugin issue Test Procedure: build should be successful Risk: low Priority: P2 --- src/JavaScriptContextBase.cpp | 19 ++++++++++++++++--- src/NativeJSLogger.cpp | 18 +++++++++--------- src/NativeJSRenderer.cpp | 4 ++-- src/jsc/JavaScriptContext.cpp | 19 ++++++++++--------- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/JavaScriptContextBase.cpp b/src/JavaScriptContextBase.cpp index 086b7c9..8bee572 100644 --- a/src/JavaScriptContextBase.cpp +++ b/src/JavaScriptContextBase.cpp @@ -154,13 +154,26 @@ void JavaScriptContextBase::populateModulesPath() if(getenv("JSRUNTIME_MODULES_PATH")) { std::cout<<"JSRUNTIME_MODULES_PATH variable is set"<setUrl(mContextMap[id].url); - if(context->getModuleSettings().enableJSDOM) + if(context->getModuleSettings().enableMiniJSDOM) { std::stringstream window; window<<"window.location = {\"href\":\"" << url << "\"};"; @@ -378,7 +378,7 @@ void NativeJSRenderer::runApplicationInternal(ApplicationRequest& appRequest) NativeJSLogger::log(INFO, "About to launch local app\n"); JavaScriptContext* context = (JavaScriptContext*)mContextMap[id].context; context->setUrl(mContextMap[id].url); - if(context->getModuleSettings().enableJSDOM) + if(context->getModuleSettings().enableMiniJSDOM) { std::stringstream window; window<<"window.location = {\"href\":\"file:/" << url << "\"};"; diff --git a/src/jsc/JavaScriptContext.cpp b/src/jsc/JavaScriptContext.cpp index c70e11a..d9fdd8e 100644 --- a/src/jsc/JavaScriptContext.cpp +++ b/src/jsc/JavaScriptContext.cpp @@ -139,16 +139,16 @@ void JavaScriptContext::loadAAMPJSBindingsLib() if (nullptr == gAAMPJSBindings->PlayerLibHandle) { static const char *aampJSBindingsLib = "libaampjsbindings.so"; - // This is required for NativeJS Plugin - #if 0 - static const char *jscLib = "libJavaScriptCore.so"; - jscLibHandle = dlopen(jscLib, RTLD_NOW | RTLD_GLOBAL); - if (!jscLibHandle) + if(!getenv("ETHAN_LOGGING_PIPE")) { - std::cout<<"dlopen error for jsc library " << dlerror() << std::endl; + // This is required for NativeJS Plugin + static const char *jscLib = "libJavaScriptCore.so"; + jscLibHandle = dlopen(jscLib, RTLD_NOW | RTLD_GLOBAL); + if (!jscLibHandle) + { + std::cout<<"dlopen error for jsc library " << dlerror() << std::endl; + } } - #endif - void *aampJSBindingsLibHandle = dlopen(aampJSBindingsLib, RTLD_NOW | RTLD_GLOBAL); if (aampJSBindingsLibHandle) { @@ -174,7 +174,8 @@ void JavaScriptContext::unloadAAMPJSBindingsLib() if (nullptr != gAAMPJSBindings->PlayerLibHandle) { dlclose(gAAMPJSBindings->PlayerLibHandle); - //dlclose(jscLibHandle); + if(!getenv("ETHAN_LOGGING_PIPE")) + dlclose(jscLibHandle); } } From f842406b6fd114c3a48e7c08292a59b7e84c4936 Mon Sep 17 00:00:00 2001 From: gsarng517_comcast Date: Wed, 25 Feb 2026 19:53:23 +0530 Subject: [PATCH 3/4] RDKEMW-14592: Nativescript widget is not working in support branch with VIPA 1.4.2 build Reason for change: updated minified jsdom with HTML APIs Test Procedure: build should be successful Risk: low Priority: P2 --- src/jsc/modules/minified_linkedjsdom.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/jsc/modules/minified_linkedjsdom.js b/src/jsc/modules/minified_linkedjsdom.js index cb9d064..830cb0c 100644 --- a/src/jsc/modules/minified_linkedjsdom.js +++ b/src/jsc/modules/minified_linkedjsdom.js @@ -29,6 +29,26 @@ var document = { function Event(t) { this.type = t; } Event.prototype.preventDefault = function() {}; +function HTMLElement() { + this.style = {}; + this.classList = { add: function() {}, remove: function() {}, toggle: function() {}, contains: function() { return false; } }; + this.children = []; + this.childNodes = []; +} +HTMLElement.prototype.setAttribute = function() {}; +HTMLElement.prototype.getAttribute = function() { return null; }; +HTMLElement.prototype.hasAttribute = function() { return false; }; +HTMLElement.prototype.removeAttribute = function() {}; +HTMLElement.prototype.appendChild = function(c) { this.children.push(c); this.childNodes.push(c); return c; }; +HTMLElement.prototype.removeChild = function(c) { return c; }; +HTMLElement.prototype.addEventListener = function() {}; +HTMLElement.prototype.removeEventListener = function() {}; +HTMLElement.prototype.dispatchEvent = function() {}; +HTMLElement.prototype.getBoundingClientRect = function() { return {top:0,left:0,right:0,bottom:0,width:0,height:0,x:0,y:0}; }; +HTMLElement.prototype.focus = function() {}; +HTMLElement.prototype.blur = function() {}; +HTMLElement.prototype.click = function() {}; + function DOMParser() {} DOMParser.prototype.parseFromString = function() { return document; }; @@ -114,11 +134,13 @@ var window = { clearInterval: wrappedClearInterval, addEventListener: function() {}, Event: Event, + HTMLElement: HTMLElement, DOMParser: DOMParser, Blob: Blob, AbortController: AbortController, fetch: fetch, - Promise: Promise + Promise: Promise, + frames: { length: 0 } }; window.window = window; @@ -127,6 +149,7 @@ var navigator = window.navigator; var location = window.location; window.top = window; var tv = window.tv = {}; +var HTMLElement = window.HTMLElement; var DOMParser = window.DOMParser; var Event = window.Event; var Blob = window.Blob; From 8d44cddef89e8f1261a73894eaba8427a06984b1 Mon Sep 17 00:00:00 2001 From: Vinod Kumar Jain Date: Thu, 26 Feb 2026 20:34:53 -0600 Subject: [PATCH 4/4] 2.0.3 release changelog updates --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2445f..a080667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [2.0.3](https://github.com/rdkcentral/rdkNativeScript/compare/2.0.2...2.0.3) + +- RDKEMW-13657: Plugin Feature fails on Xione-UK [`#124`](https://github.com/rdkcentral/rdkNativeScript/pull/124) +- RDKEMW-14592: Nativescript widget is not working in support branch wi… [`#125`](https://github.com/rdkcentral/rdkNativeScript/pull/125) +- RDKEMW-13250: Memory Metrics analysis for VIPA [`#123`](https://github.com/rdkcentral/rdkNativeScript/pull/123) +- RDKEMW-14592: Nativescript widget is not working in support branch with VIPA 1.4.2 build [`f842406`](https://github.com/rdkcentral/rdkNativeScript/commit/f842406b6fd114c3a48e7c08292a59b7e84c4936) +- Merge tag '2.0.2' into develop [`7b4569c`](https://github.com/rdkcentral/rdkNativeScript/commit/7b4569c6c31487c0640f5bc9afa3158d83fa1271) + #### [2.0.2](https://github.com/rdkcentral/rdkNativeScript/compare/2.0.1...2.0.2) - Fix High and Medium Level issues [`#110`](https://github.com/rdkcentral/rdkNativeScript/pull/110)