From 749f89d0af61e7aab7d96cb70a392e4efb8f8020 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 19 Mar 2026 20:12:56 +0530 Subject: [PATCH 01/52] Changes for the error and uninstall overlay screen then some bug fixes also part of this --- accelerator-home-ui/src/App.js | 58 ++-- accelerator-home-ui/src/AppController.js | 26 +- accelerator-home-ui/src/items/AppCard.js | 5 +- .../src/items/AppCatalogItem.js | 8 +- accelerator-home-ui/src/items/DacAppItem.js | 13 +- .../src/keyIntercept/keyIntercept.js | 39 ++- .../src/overlays/UninstallConfirmation.js | 297 ++++++++++++++++++ accelerator-home-ui/src/routes/routes.js | 6 +- .../src/screens/FailAndOkScreen.js | 123 ++++++++ accelerator-home-ui/src/views/AppInfoPage.js | 76 ++++- accelerator-home-ui/src/views/AppStore.js | 27 ++ accelerator-home-ui/src/views/MainView.js | 49 ++- 12 files changed, 644 insertions(+), 83 deletions(-) create mode 100644 accelerator-home-ui/src/overlays/UninstallConfirmation.js create mode 100644 accelerator-home-ui/src/screens/FailAndOkScreen.js diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index c86832c..86b06ea 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -35,6 +35,7 @@ import { import Keymap from './Config/Keymap'; import Menu from './views/Menu' import Failscreen from './screens/FailScreen'; +import FailAndOkScreen from './screens/FailAndOkScreen'; import { keyIntercept } from './keyIntercept/keyIntercept'; @@ -193,6 +194,9 @@ export default class App extends Router.App { Fail: { type: Failscreen, }, + FailOk: { + type: FailAndOkScreen, + }, Volume: { type: Volume }, @@ -514,7 +518,7 @@ export default class App extends Router.App { "Prime": "n:2" } this._getPowerStatebeforeReboot(); - this._registerFireboltListeners() + // this._registerFireboltListeners() Keyboard.provide('xrn:firebolt:capability:input:keyboard', new KeyboardUIProvider(this)) this.LOG("Keyboard provider registered") @@ -1704,32 +1708,32 @@ export default class App extends Router.App { this._getPowerStateWhileReboot(); }); } - _registerFireboltListeners() { - FireBoltApi.get().deviceinfo.gettype() - FireBoltApi.get().lifecycle.ready() - - FireBoltApi.get().lifecycle.registerEvent('foreground', value => { - this.LOG("FireBoltApi[foreground] value:" + JSON.stringify(value) + ", launchResidentApp with:" + JSON.stringify(GLOBALS.selfClientName)); - // Ripple launches refui with this rdkshell client name. - GLOBALS.topmostApp = GLOBALS.selfClientName; - FireBoltApi.get().discovery.launch("refui", { - "action": "home", - "context": { - "source": "device" - } - }).then(() => { - AlexaApi.get().reportApplicationState("menu", true); - }) - }) - FireBoltApi.get().lifecycle.registerEvent('background', value => { - // Ripple changed app states; it will be a 'FireboltApp' - GLOBALS.topmostApp = "FireboltApp"; - this.LOG("FireBoltApi[foreground] value:" + JSON.stringify(value) + ", Updating top app as:" + JSON.stringify(GLOBALS.topmostApp)); - }) - FireBoltApi.get().lifecycle.state().then(res => { - this.LOG("Lifecycle.state result:" + JSON.stringify(res)) - }); - } + // _registerFireboltListeners() { + // FireBoltApi.get().deviceinfo.gettype() + // FireBoltApi.get().lifecycle.ready() + + // FireBoltApi.get().lifecycle.registerEvent('foreground', value => { + // this.LOG("FireBoltApi[foreground] value:" + JSON.stringify(value) + ", launchResidentApp with:" + JSON.stringify(GLOBALS.selfClientName)); + // // Ripple launches refui with this rdkshell client name. + // GLOBALS.topmostApp = GLOBALS.selfClientName; + // FireBoltApi.get().discovery.launch("refui", { + // "action": "home", + // "context": { + // "source": "device" + // } + // }).then(() => { + // AlexaApi.get().reportApplicationState("menu", true); + // }) + // }) + // FireBoltApi.get().lifecycle.registerEvent('background', value => { + // // Ripple changed app states; it will be a 'FireboltApp' + // GLOBALS.topmostApp = "FireboltApp"; + // this.LOG("FireBoltApi[foreground] value:" + JSON.stringify(value) + ", Updating top app as:" + JSON.stringify(GLOBALS.topmostApp)); + // }) + // FireBoltApi.get().lifecycle.state().then(res => { + // this.LOG("Lifecycle.state result:" + JSON.stringify(res)) + // }); + // } _firstEnable() { this.LOG("App Calling listenToVoiceControl method to activate VoiceControl Plugin") diff --git a/accelerator-home-ui/src/AppController.js b/accelerator-home-ui/src/AppController.js index 4ae3d35..5a4a564 100644 --- a/accelerator-home-ui/src/AppController.js +++ b/accelerator-home-ui/src/AppController.js @@ -175,25 +175,15 @@ export default class AppController { async addKeyIntercepts(appId, clientId) { if (appId === "com.rdkcentral.youtube") { try { + const intercepts = [ + { "keyCode": Keymap.AudioVolumeMute, "modifiers": [] }, + { "keyCode": Keymap.AudioVolumeDown, "modifiers": [] }, + { "keyCode": Keymap.AudioVolumeUp, "modifiers": [] }, + { "keyCode": Keymap.Youtube, "modifiers": [] } + ]; await RDKWindowManager.get().addKeyIntercepts({ - "intercepts": { - "intercepts": [{ - "keys": [{ - "keyCode": Keymap.AudioVolumeMute, - "modifiers": [] - }, { - "keyCode": Keymap.AudioVolumeDown, - "modifiers": [] - }, { - "keyCode": Keymap.AudioVolumeUp, - "modifiers": [] - }, { - "keyCode": Keymap.Youtube, - "modifiers": [] - }], - "client": clientId - }] - } + "clientId": clientId, + "intercepts": JSON.stringify(intercepts) }); } catch (err) { throw new ThunderError("RDKWindowManager.addKeyIntercepts()", err); diff --git a/accelerator-home-ui/src/items/AppCard.js b/accelerator-home-ui/src/items/AppCard.js index 52d5582..7aee6b4 100644 --- a/accelerator-home-ui/src/items/AppCard.js +++ b/accelerator-home-ui/src/items/AppCard.js @@ -66,9 +66,6 @@ class ActionButton extends Lightning.Component { set primary(isPrimary) { this._isPrimary = isPrimary; - if (isPrimary) { - this.patch({ color: CONFIG.theme.hex }); - } } get primary() { @@ -97,7 +94,7 @@ class ActionButton extends Lightning.Component { _unfocus() { this.tag('FocusIndicator').alpha = 0; this.patch({ - color: this._isPrimary ? CONFIG.theme.hex : 0xFF3D3D3D, + color: 0xFF3D3D3D, smooth: { scale: 1 } }); } diff --git a/accelerator-home-ui/src/items/AppCatalogItem.js b/accelerator-home-ui/src/items/AppCatalogItem.js index 5922135..a52d8d8 100644 --- a/accelerator-home-ui/src/items/AppCatalogItem.js +++ b/accelerator-home-ui/src/items/AppCatalogItem.js @@ -50,6 +50,7 @@ export const DACAppMixin = (Base) => class extends Base { this.updateDACStatus(statusProgressTag, overlayTag) if (!success) { this.tag(statusProgressTag).setProgress(1.0, 'Error: ' + msg) + this.fireAncestors('$showInstallError', { name: this._app.name, errorCode: msg || -1 }) } return true; // Installation operation completed } else if (this._app.isUnInstalling) { @@ -58,6 +59,7 @@ export const DACAppMixin = (Base) => class extends Base { this.updateDACStatus(statusProgressTag, overlayTag) if (!success) { this.tag(statusProgressTag).setProgress(1.0, 'Error: ' + msg) + this.fireAncestors('$showUninstallError', { name: this._app.name, error: msg }) } return true; // Uninstall operation completed } @@ -97,10 +99,12 @@ export const DACAppMixin = (Base) => class extends Base { } else { this.ERR("Failed to launch app: " + this._app.name) this.tag(overlayTag + '.OverlayText').text.text = Language.translate('Launch failed'); + this.fireAncestors('$showLaunchError', { name: this._app.name }); } } catch (err) { this.ERR("Error launching app: " + JSON.stringify(err)) this.tag(overlayTag + '.OverlayText').text.text = Language.translate('Launch failed'); + this.fireAncestors('$showLaunchError', { name: this._app.name, error: err.message || err }); } this.tag(overlayTag).setSmooth('alpha', 0, { duration: 5 }) return true; // Already installed @@ -117,10 +121,12 @@ export const DACAppMixin = (Base) => class extends Base { this._app.isInstalling = true; if (!await installDACApp(this._app, this.tag(statusProgressTag))) { this._app.isInstalling = false; - this.tag(overlayTag + '.OverlayText').text.text = Language.translate("Status") + ':' + (this._app.errorCode ?? -1); + const errorCode = this._app.errorCode ?? -1; + this.tag(overlayTag + '.OverlayText').text.text = Language.translate("Status") + ':' + errorCode; this.tag(overlayTag).alpha = 0.7 this.tag(overlayTag + '.OverlayText').alpha = 1 this.tag(overlayTag).setSmooth('alpha', 0, { duration: 5 }) + this.fireAncestors('$showInstallError', { name: this._app.name, errorCode: errorCode }); return false; } return true; diff --git a/accelerator-home-ui/src/items/DacAppItem.js b/accelerator-home-ui/src/items/DacAppItem.js index 006c604..28319c1 100644 --- a/accelerator-home-ui/src/items/DacAppItem.js +++ b/accelerator-home-ui/src/items/DacAppItem.js @@ -189,7 +189,14 @@ export default class DacAppItem extends DACAppMixin(Lightning.Component) { if (this._app.isInstalled) { this.LOG("App is already installed, launching...") // Launch the installed app - this._app.isRunning = await startDACApp(this._app); + try { + this._app.isRunning = await startDACApp(this._app); + if (!this._app.isRunning) { + this.fireAncestors('$showLaunchError', { name: this._app.name }); + } + } catch (err) { + this.fireAncestors('$showLaunchError', { name: this._app.name, error: err.message || err }); + } return } await this.performDACInstall('ImageWrapper.StatusProgress', 'ImageWrapper.Overlay'); @@ -244,6 +251,10 @@ export default class DacAppItem extends DACAppMixin(Lightning.Component) { async _handleEnter() { // Handle "More Apps" item - navigate to apps route if (this.data.applicationType === 'MoreApps') { + if (!GLOBALS.IsConnectedToInternet) { + this.fireAncestors('$showNetworkError') + return + } Router.navigate('apps'); return; } diff --git a/accelerator-home-ui/src/keyIntercept/keyIntercept.js b/accelerator-home-ui/src/keyIntercept/keyIntercept.js index d810cfb..f7ba8ba 100644 --- a/accelerator-home-ui/src/keyIntercept/keyIntercept.js +++ b/accelerator-home-ui/src/keyIntercept/keyIntercept.js @@ -26,29 +26,26 @@ const thunder = ThunderJS(CONFIG.thunderConfig); export function keyIntercept(clientName = GLOBALS.selfClientId) { return new Promise((resolve, reject) => { + const intercepts = [ + { "keyCode": Keymap.Home, "modifiers": [] }, + { "keyCode": Keymap.AudioVolumeDown, "modifiers": [] }, + { "keyCode": Keymap.AudioVolumeUp, "modifiers": [] }, + { "keyCode": Keymap.AudioVolumeMute, "modifiers": [] }, + { "keyCode": Keymap.Inputs_Shortcut, "modifiers": [] }, + { "keyCode": Keymap.Picture_Setting_Shortcut, "modifiers": [] }, + { "keyCode": Keymap.Youtube, "modifiers": [] }, + { "keyCode": Keymap.Power, "modifiers": [] }, + { "keyCode": Keymap.Amazon, "modifiers": [] }, + { "keyCode": Keymap.Netflix, "modifiers": [] }, + { "keyCode": Keymap.Settings_Shortcut, "modifiers": [] }, + { "keyCode": Keymap.Guide_Shortcut, "modifiers": [] }, + { "keyCode": Keymap.AppCarousel, "modifiers": [] }, + { "keyCode": Keymap.Escape, "modifiers": [] } + ]; RDKWindowManager.get().addKeyIntercepts( { - "intercepts":{ - "intercepts": [{ - "keys": [ - { "keyCode": Keymap.Home, "modifiers": [] }, - { "keyCode": Keymap.AudioVolumeDown, "modifiers": [] }, - { "keyCode": Keymap.AudioVolumeUp, "modifiers": [] }, - { "keyCode": Keymap.AudioVolumeMute, "modifiers": [] }, - { "keyCode": Keymap.Inputs_Shortcut, "modifiers": [] }, - { "keyCode": Keymap.Picture_Setting_Shortcut, "modifiers": [] }, - { "keyCode": Keymap.Youtube, "modifiers": [] }, - { "keyCode": Keymap.Power, "modifiers": [] }, - { "keyCode": Keymap.Amazon, "modifiers": [] }, - { "keyCode": Keymap.Netflix, "modifiers": [] }, - { "keyCode": Keymap.Settings_Shortcut, "modifiers": [] }, - { "keyCode": Keymap.Guide_Shortcut, "modifiers": [] }, - { "keyCode": Keymap.AppCarousel, "modifiers": [] }, - { "keyCode": Keymap.Escape, "modifiers": [] } - ], - "client": clientName, - }] - }, + "clientId": clientName, + "intercepts": JSON.stringify(intercepts) } ).then(result => { if (result.success) { diff --git a/accelerator-home-ui/src/overlays/UninstallConfirmation.js b/accelerator-home-ui/src/overlays/UninstallConfirmation.js new file mode 100644 index 0000000..3190ce3 --- /dev/null +++ b/accelerator-home-ui/src/overlays/UninstallConfirmation.js @@ -0,0 +1,297 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +import { Lightning, Utils, Language } from "@lightningjs/sdk"; +import { CONFIG } from "../Config/Config"; + +/** + * Class for Uninstall Confirmation Overlay Component. + */ +export default class UninstallConfirmation extends Lightning.Component { + static _template() { + return { + rect: true, + w: 1920, + h: 1080, + color: 0xCC000000, // Semi-transparent black background + zIndex: 10, + UninstallDialog: { + x: 960, + y: 540, + mount: 0.5, + rect: true, + w: 620, + h: 320, + color: 0xFF1A1A1A, + shader: { + type: Lightning.shaders.RoundedRectangle, + radius: 16, + }, + DialogBorder: { + x: -2, + y: -2, + w: 624, + h: 324, + rect: true, + color: 0x00000000, + shader: { + type: Lightning.shaders.RoundedRectangle, + radius: 18, + stroke: 2, + strokeColor: 0xFF3D3D3D, + }, + }, + Title: { + x: 310, + y: 40, + mountX: 0.5, + text: { + text: Language.translate("Uninstall"), + fontFace: CONFIG.language.font, + fontSize: 36, + textColor: CONFIG.theme.hex, + fontStyle: "bold", + }, + }, + BorderTop: { + x: 30, + y: 90, + w: 560, + h: 2, + rect: true, + color: 0xFF3D3D3D, + }, + Info: { + x: 310, + y: 130, + mountX: 0.5, + text: { + text: Language.translate("Are you sure you want to uninstall this app?"), + fontFace: CONFIG.language.font, + fontSize: 24, + textColor: 0xFFCCCCCC, + textAlign: "center", + wordWrapWidth: 520, + }, + }, + AppName: { + x: 310, + y: 170, + mountX: 0.5, + text: { + text: "", + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xFFAAAAAA, + textAlign: "center", + wordWrapWidth: 520, + }, + }, + Buttons: { + x: 310, + y: 230, + mountX: 0.5, + w: 440, + h: 50, + Confirm: { + x: 0, + w: 200, + h: 50, + rect: true, + color: 0xFFFFFFFF, + shader: { + type: Lightning.shaders.RoundedRectangle, + radius: 8, + }, + Title: { + x: 100, + y: 25, + mount: 0.5, + text: { + text: Language.translate("Confirm"), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xFF000000, + }, + }, + }, + Cancel: { + x: 220, + w: 200, + h: 50, + rect: true, + color: 0xFF7D7D7D, + shader: { + type: Lightning.shaders.RoundedRectangle, + radius: 8, + }, + Title: { + x: 100, + y: 25, + mount: 0.5, + text: { + text: Language.translate("Cancel"), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xFF000000, + }, + }, + }, + }, + Loader: { + x: 310, + y: 160, + mountX: 0.5, + w: 90, + h: 90, + zIndex: 2, + src: Utils.asset("images/settings/Loading.png"), + visible: false, + }, + }, + }; + } + + /** + * Set the app info for the uninstall confirmation + * @param {Object} appInfo - App data (id, name, version, etc.) + */ + set appInfo(data) { + this._appInfo = data; + const appName = data.name || data.appName || "Unknown App"; + this.tag("UninstallDialog.AppName").text.text = `"${appName}"`; + } + + get appInfo() { + return this._appInfo; + } + + _focus() { + this._setState("Confirm"); + + this.loadingAnimation = this.tag("UninstallDialog.Loader").animation({ + duration: 3, + repeat: -1, + stopMethod: "immediate", + stopDelay: 0.2, + actions: [{ p: "rotation", v: { sm: 0, 0: 0, 1: 2 * Math.PI } }], + }); + } + + static _states() { + return [ + class Confirm extends this { + $enter() { + this._focus(); + } + _handleEnter() { + this.fireAncestors("$confirmUninstall", this._appInfo); + } + _handleRight() { + this._setState("Cancel"); + } + _handleBack() { + this.fireAncestors("$cancelUninstall"); + } + _focus() { + this.tag("Buttons.Confirm").patch({ + color: CONFIG.theme.hex, + }); + this.tag("Buttons.Confirm.Title").patch({ + text: { textColor: 0xFFFFFFFF }, + }); + } + _unfocus() { + this.tag("Buttons.Confirm").patch({ + color: 0xFFFFFFFF, + }); + this.tag("Buttons.Confirm.Title").patch({ + text: { textColor: 0xFF000000 }, + }); + } + $exit() { + this._unfocus(); + } + }, + class Cancel extends this { + $enter() { + this._focus(); + } + _handleEnter() { + this.fireAncestors("$cancelUninstall"); + } + _handleLeft() { + this._setState("Confirm"); + } + _handleBack() { + this.fireAncestors("$cancelUninstall"); + } + _focus() { + this.tag("Buttons.Cancel").patch({ + color: CONFIG.theme.hex, + }); + this.tag("Buttons.Cancel.Title").patch({ + text: { textColor: 0xFFFFFFFF }, + }); + } + _unfocus() { + this.tag("Buttons.Cancel").patch({ + color: 0xFF7D7D7D, + }); + this.tag("Buttons.Cancel.Title").patch({ + text: { textColor: 0xFF000000 }, + }); + } + $exit() { + this._unfocus(); + } + }, + class Uninstalling extends this { + $enter() { + this.loadingAnimation.start(); + this.tag("UninstallDialog.Loader").visible = true; + this.tag("UninstallDialog.Title").text.text = Language.translate("Uninstalling") + "..."; + this.tag("UninstallDialog.Buttons").visible = false; + this.tag("UninstallDialog.Info").visible = false; + this.tag("UninstallDialog.AppName").visible = false; + } + $exit() { + this.loadingAnimation.stop(); + this.tag("UninstallDialog.Loader").visible = false; + this.tag("UninstallDialog.Title").text.text = Language.translate("Uninstall"); + this.tag("UninstallDialog.Buttons").visible = true; + this.tag("UninstallDialog.Info").visible = true; + this.tag("UninstallDialog.AppName").visible = true; + } + _handleEnter() { /* do nothing */ } + _handleLeft() { /* do nothing */ } + _handleRight() { /* do nothing */ } + _handleBack() { /* do nothing */ } + _handleUp() { /* do nothing */ } + _handleDown() { /* do nothing */ } + }, + ]; + } + + /** + * Show the uninstalling state with loader + */ + showUninstalling() { + this._setState("Uninstalling"); + } +} diff --git a/accelerator-home-ui/src/routes/routes.js b/accelerator-home-ui/src/routes/routes.js index bafef6c..7f99815 100644 --- a/accelerator-home-ui/src/routes/routes.js +++ b/accelerator-home-ui/src/routes/routes.js @@ -101,12 +101,12 @@ export default { { path: 'apps', component: AppStore, - widgets: ['Menu', 'Volume', "AppCarousel"] + widgets: ['Menu', 'FailOk', 'Volume', "AppCarousel"] }, { path: 'appinfo', component: AppInfoPage, - widgets: ['Menu', 'Volume', "AppCarousel"] + widgets: ['Menu', 'FailOk', 'Volume', "AppCarousel"] }, { path: 'usb/player', @@ -140,7 +140,7 @@ export default { } return Promise.resolve() }, - widgets: ['Menu', 'Fail', 'Volume','MiracastNotification', "AppCarousel", "VideoInfoChange"], + widgets: ['Menu', 'Fail', 'FailOk', 'Volume','MiracastNotification', "AppCarousel", "VideoInfoChange"], }, { path: 'tv-overlay/:type', diff --git a/accelerator-home-ui/src/screens/FailAndOkScreen.js b/accelerator-home-ui/src/screens/FailAndOkScreen.js new file mode 100644 index 0000000..f638cc0 --- /dev/null +++ b/accelerator-home-ui/src/screens/FailAndOkScreen.js @@ -0,0 +1,123 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +import { Language, Lightning, Router } from "@lightningjs/sdk"; +import { CONFIG } from '../Config/Config' + +const errorTitle = 'Error Title' +const errorMsg = 'Error Message' +export default class FailAndOkScreen extends Lightning.Component { + + constructor(...args) { + super(...args); + this.INFO = console.info; + this.LOG = console.log; + this.ERR = console.error; + this.WARN = console.warn; + } + + notify(args) { + this.LOG("notify args: " + JSON.stringify(args)) + if (args.title && args.msg) { + this.tag('FailScreen.Title').text.text = args.title + this.tag('FailScreen.Message').text.text = Language.translate(args.msg) + } + } + + pageTransition() { + return 'left' + } + + _focus() { + this.LOG("FailAndOkScreen _focus() called, alpha before: " + this.alpha) + this.alpha = 1 + this.LOG("FailAndOkScreen _focus() alpha set to 1") + this.tag('FailScreen.OkButton').color = CONFIG.theme.hex + this.tag('FailScreen.OkButton.OkLabel').text.textColor = 0xFFFFFFFF + } + + _unfocus() { + this.alpha = 0 + this.tag('FailScreen.Title').text.text = errorTitle + this.tag('FailScreen.Message').text.text = errorMsg + this.tag('FailScreen.OkButton').color = 0xFFFFFFFF + this.tag('FailScreen.OkButton.OkLabel').text.textColor = 0xFF000000 + } + + static _template() { + return { + alpha: 0, + w: 1920, + h: 1080, + rect: true, + color: 0xcc000000, + FailScreen: { + x: 960, + y: 300, + Title: { + mountX: 0.5, + text: { + text: errorTitle, + fontFace: CONFIG.language.font, + fontSize: 40, + textColor: CONFIG.theme.hex, + }, + }, + BorderTop: { + x: 0, y: 75, w: 1558, h: 3, rect: true, mountX: 0.5, + }, + Message: { + x: 0, + y: 125, + mountX: 0.5, + text: { + text: errorMsg, + fontFace: CONFIG.language.font, + fontSize: 25, + }, + }, + OkButton: { + x: 0, y: 200, w: 200, mountX: 0.5, h: 50, rect: true, color: 0xFFFFFFFF, + OkLabel: { + x: 100, + y: 25, + mount: 0.5, + text: { + text: Language.translate("OK"), + fontFace: CONFIG.language.font, + fontSize: 25, + textColor: 0xFF000000, + }, + }, + }, + BorderBottom: { + x: 0, y: 300, w: 1558, h: 3, rect: true, mountX: 0.5, + }, + }, + }; + } + + _handleEnter() { + Router.focusPage() + } + + _handleBack() { + Router.focusPage() + } + +} diff --git a/accelerator-home-ui/src/views/AppInfoPage.js b/accelerator-home-ui/src/views/AppInfoPage.js index 9070e46..1e17697 100644 --- a/accelerator-home-ui/src/views/AppInfoPage.js +++ b/accelerator-home-ui/src/views/AppInfoPage.js @@ -23,6 +23,7 @@ import { CONFIG, GLOBALS } from "../Config/Config"; import AppCard from "../items/AppCard"; import { getInstalledDACApps, startDACApp, uninstallDACApp } from "../api/DACApi"; import { filterExcludedApps } from "../helpers/DACAppPresentation"; +import UninstallConfirmation from "../overlays/UninstallConfirmation"; export default class AppInfoPage extends Lightning.Component { @@ -158,6 +159,13 @@ export default class AppInfoPage extends Lightning.Component { } } } + }, + + // Uninstall Confirmation Overlay + UninstallConfirmationOverlay: { + type: UninstallConfirmation, + visible: false, + zIndex: 10 } } } @@ -247,7 +255,7 @@ export default class AppInfoPage extends Lightning.Component { break; case 'uninstall': console.log("Uninstall app:", appInfo.name); - this._uninstallApp(appInfo); + this._showUninstallConfirmation(appInfo); break; default: console.log("Unknown action:", action); @@ -293,14 +301,67 @@ export default class AppInfoPage extends Lightning.Component { console.log(`${appInfo.name} uninstalled successfully`); // Refresh the list after uninstall await this._fetchInstalledApps(); + return true; } else { console.error(`Failed to uninstall ${appInfo.name}`); + return false; } } catch (error) { console.error(`Error uninstalling ${appInfo.name}:`, error); + return false; + } + } + + /** + * Show the uninstall confirmation overlay + */ + _showUninstallConfirmation(appInfo) { + this._pendingUninstallApp = appInfo; + this.tag('UninstallConfirmationOverlay').appInfo = appInfo; + this.tag('UninstallConfirmationOverlay').visible = true; + this._setState('UninstallConfirmation'); + } + + /** + * Hide the uninstall confirmation overlay + */ + _hideUninstallConfirmation() { + this.tag('UninstallConfirmationOverlay').visible = false; + this._pendingUninstallApp = null; + // Set correct state based on whether apps remain + if (this._appData.length > 0) { + this._setState('AppList'); + } else { + this._setState('EmptyState'); } } + /** + * Signal handler: user confirmed uninstall + */ + $confirmUninstall(appInfo) { + console.log('Uninstall confirmed for:', appInfo.name); + this.tag('UninstallConfirmationOverlay').showUninstalling(); + this._uninstallApp(appInfo).then((success) => { + this._hideUninstallConfirmation(); + if (!success) { + this.widgets.failok.notify({ + title: Language.translate('Uninstall Failed'), + msg: Language.translate('Failed to uninstall') + ` "${appInfo.name}". ` + Language.translate('Please try again later.'), + }); + Router.focusWidget('FailOk'); + } + }); + } + + /** + * Signal handler: user cancelled uninstall + */ + $cancelUninstall() { + console.log('Uninstall cancelled'); + this._hideUninstallConfirmation(); + } + /** * Update scroll indicator position */ @@ -378,6 +439,17 @@ export default class AppInfoPage extends Lightning.Component { return false; } }, + class UninstallConfirmation extends this { + $enter() { + this.tag('UninstallConfirmationOverlay').visible = true; + } + _getFocused() { + return this.tag('UninstallConfirmationOverlay'); + } + $exit() { + this.tag('UninstallConfirmationOverlay').visible = false; + } + }, class EmptyState extends this { $enter() { this.tag('EmptyState.OkButton').color = CONFIG.theme.hex; @@ -393,6 +465,8 @@ export default class AppInfoPage extends Lightning.Component { return this; } _focus() { + // Re-fetch installed apps in case new apps were installed while away + this._fetchInstalledApps(); this.tag('EmptyState.OkButton').color = CONFIG.theme.hex; this.tag('EmptyState.OkButton.OkLabel').text.textColor = 0xFFFFFFFF; this.tag('EmptyState.OkButton.FocusBorder').alpha = 1; diff --git a/accelerator-home-ui/src/views/AppStore.js b/accelerator-home-ui/src/views/AppStore.js index 083d1d5..5c621bc 100644 --- a/accelerator-home-ui/src/views/AppStore.js +++ b/accelerator-home-ui/src/views/AppStore.js @@ -78,6 +78,33 @@ export default class AppStore extends Lightning.Component { this._setState('Catalog') } + $showInstallError({ name, errorCode }) { + const appName = name || Language.translate('App') + const msg = Language.translate('Something went wrong while installing') + ` "${appName}". ` + Language.translate('Error code') + `: ${errorCode}` + this.widgets.failok.notify({ title: Language.translate('Installation Failed'), msg: msg }) + Router.focusWidget('FailOk') + } + + $showUninstallError({ name, error }) { + const appName = name || Language.translate('App') + let msg = Language.translate('Failed to uninstall') + ` "${appName}". ` + Language.translate('Please try again later.') + if (error) { + msg += ' ' + Language.translate('Error') + `: ${error}` + } + this.widgets.failok.notify({ title: Language.translate('Uninstall Failed'), msg: msg }) + Router.focusWidget('FailOk') + } + + $showLaunchError({ name, error }) { + const appName = name || Language.translate('App') + let msg = Language.translate('Something went wrong while launching') + ` "${appName}". ` + Language.translate('Please check the internet and remaining setup.') + if (error) { + msg += ' ' + Language.translate('Error') + `: ${error}` + } + this.widgets.failok.notify({ title: Language.translate('Launch Failed'), msg: msg }) + Router.focusWidget('FailOk') + } + static _states() { return [ class Catalog extends this { diff --git a/accelerator-home-ui/src/views/MainView.js b/accelerator-home-ui/src/views/MainView.js index 27c258a..b07e3dc 100644 --- a/accelerator-home-ui/src/views/MainView.js +++ b/accelerator-home-ui/src/views/MainView.js @@ -718,8 +718,35 @@ export default class MainView extends Lightning.Component { } } $showNetworkError() { - this.widgets.fail.notify({ title: 'Network State', msg: 'Offline' }) - Router.focusWidget('Fail') + this.widgets.failok.notify({ title: Language.translate('No Internet'), msg: Language.translate('No internet connection. Please check your network and try again.') }) + Router.focusWidget('FailOk') + } + + $showInstallError({ name, errorCode }) { + const appName = name || Language.translate('App') + const msg = Language.translate('Something went wrong while installing') + ` "${appName}". ` + Language.translate('Error code') + `: ${errorCode}` + this.widgets.failok.notify({ title: Language.translate('Installation Failed'), msg: msg }) + Router.focusWidget('FailOk') + } + + $showUninstallError({ name, error }) { + const appName = name || Language.translate('App') + let msg = Language.translate('Failed to uninstall') + ` "${appName}". ` + Language.translate('Please try again later.') + if (error) { + msg += ' ' + Language.translate('Error') + `: ${error}` + } + this.widgets.failok.notify({ title: Language.translate('Uninstall Failed'), msg: msg }) + Router.focusWidget('FailOk') + } + + $showLaunchError({ name, error }) { + const appName = name || Language.translate('App') + let msg = Language.translate('Something went wrong while launching') + ` "${appName}". ` + Language.translate('Please check the internet and remaining setup.') + if (error) { + msg += ' ' + Language.translate('Error') + `: ${error}` + } + this.widgets.failok.notify({ title: Language.translate('Launch Failed'), msg: msg }) + Router.focusWidget('FailOk') } /** @@ -925,10 +952,11 @@ export default class MainView extends Lightning.Component { }) } else if (applicationType === 'DAC') { // Launch DAC app using startDACApp - if (!GLOBALS.IsConnectedToInternet) { - this.fireAncestors('$showNetworkError') - return - } + // if (!GLOBALS.IsConnectedToInternet) { + // console.log('No internet connection. Cannot launch DAC app.') + // this.$showNetworkError() + // return + // } let dacApp = { id: appIdentifier || uri, name: appData.displayName, @@ -937,7 +965,14 @@ export default class MainView extends Lightning.Component { url: uri } this.LOG('Launching DAC app from My Apps: ' + JSON.stringify(dacApp)) - startDACApp(dacApp) + try { + const launched = await startDACApp(dacApp) + if (!launched) { + this.$showLaunchError({ name: appData.displayName }) + } + } catch (err) { + this.$showLaunchError({ name: appData.displayName, error: err.message || err }) + } } } }, From bd9385e873bffa2cdd772ad536cf034f27717c89 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Fri, 20 Mar 2026 13:36:02 +0530 Subject: [PATCH 02/52] Addressed the review comments --- accelerator-home-ui/src/items/AppCard.js | 9 --------- .../src/overlays/UninstallConfirmation.js | 17 +++++++++++++++++ accelerator-home-ui/src/views/AppInfoPage.js | 5 +++-- accelerator-home-ui/src/views/MainView.js | 10 +++++----- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/accelerator-home-ui/src/items/AppCard.js b/accelerator-home-ui/src/items/AppCard.js index 7aee6b4..a5badc6 100644 --- a/accelerator-home-ui/src/items/AppCard.js +++ b/accelerator-home-ui/src/items/AppCard.js @@ -64,14 +64,6 @@ class ActionButton extends Lightning.Component { this.tag('Label').text.text = text; } - set primary(isPrimary) { - this._isPrimary = isPrimary; - } - - get primary() { - return this._isPrimary || false; - } - set action(actionType) { this._action = actionType; } @@ -190,7 +182,6 @@ export default class AppCard extends Lightning.Component { x: 0, type: ActionButton, label: Language.translate('Launch'), - primary: true, action: 'launch' }, UpdateButton: { diff --git a/accelerator-home-ui/src/overlays/UninstallConfirmation.js b/accelerator-home-ui/src/overlays/UninstallConfirmation.js index 3190ce3..cc146d6 100644 --- a/accelerator-home-ui/src/overlays/UninstallConfirmation.js +++ b/accelerator-home-ui/src/overlays/UninstallConfirmation.js @@ -193,6 +193,23 @@ export default class UninstallConfirmation extends Lightning.Component { }); } + /** + * Safety-net cleanup when the overlay loses focus (e.g. parent hides or + * navigates away). Ensures the loader animation is stopped and the dialog + * UI is restored to its default state even if no explicit state transition + * (Uninstalling → Confirm) was triggered before dismissal. + */ + _unfocus() { + if (this.loadingAnimation && this.loadingAnimation.isActive()) { + this.loadingAnimation.stop(); + } + this.tag("UninstallDialog.Loader").visible = false; + this.tag("UninstallDialog.Title").text.text = Language.translate("Uninstall"); + this.tag("UninstallDialog.Buttons").visible = true; + this.tag("UninstallDialog.Info").visible = true; + this.tag("UninstallDialog.AppName").visible = true; + } + static _states() { return [ class Confirm extends this { diff --git a/accelerator-home-ui/src/views/AppInfoPage.js b/accelerator-home-ui/src/views/AppInfoPage.js index 1e17697..8af8e3c 100644 --- a/accelerator-home-ui/src/views/AppInfoPage.js +++ b/accelerator-home-ui/src/views/AppInfoPage.js @@ -316,7 +316,6 @@ export default class AppInfoPage extends Lightning.Component { * Show the uninstall confirmation overlay */ _showUninstallConfirmation(appInfo) { - this._pendingUninstallApp = appInfo; this.tag('UninstallConfirmationOverlay').appInfo = appInfo; this.tag('UninstallConfirmationOverlay').visible = true; this._setState('UninstallConfirmation'); @@ -326,8 +325,10 @@ export default class AppInfoPage extends Lightning.Component { * Hide the uninstall confirmation overlay */ _hideUninstallConfirmation() { + // Reset overlay to its initial state so that Uninstalling.$exit() runs, + // stopping the loader animation and restoring hidden UI elements. + this.tag('UninstallConfirmationOverlay')._setState('Confirm'); this.tag('UninstallConfirmationOverlay').visible = false; - this._pendingUninstallApp = null; // Set correct state based on whether apps remain if (this._appData.length > 0) { this._setState('AppList'); diff --git a/accelerator-home-ui/src/views/MainView.js b/accelerator-home-ui/src/views/MainView.js index b07e3dc..f31a73e 100644 --- a/accelerator-home-ui/src/views/MainView.js +++ b/accelerator-home-ui/src/views/MainView.js @@ -952,11 +952,11 @@ export default class MainView extends Lightning.Component { }) } else if (applicationType === 'DAC') { // Launch DAC app using startDACApp - // if (!GLOBALS.IsConnectedToInternet) { - // console.log('No internet connection. Cannot launch DAC app.') - // this.$showNetworkError() - // return - // } + if (!GLOBALS.IsConnectedToInternet) { + console.log('No internet connection. Cannot launch DAC app.') + this.$showNetworkError() + return + } let dacApp = { id: appIdentifier || uri, name: appData.displayName, From fff83e41c11b689df2dc261dd41cdfa5f5bd1de2 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Fri, 20 Mar 2026 14:09:13 +0530 Subject: [PATCH 03/52] Addressed the review comments --- .../src/items/AppCatalogItem.js | 3 +++ .../src/overlays/StatusProgress.js | 1 + .../src/screens/FailAndOkScreen.js | 2 +- accelerator-home-ui/src/views/AppInfoPage.js | 26 +++++++++---------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/accelerator-home-ui/src/items/AppCatalogItem.js b/accelerator-home-ui/src/items/AppCatalogItem.js index a52d8d8..25e16da 100644 --- a/accelerator-home-ui/src/items/AppCatalogItem.js +++ b/accelerator-home-ui/src/items/AppCatalogItem.js @@ -118,6 +118,9 @@ export const DACAppMixin = (Base) => class extends Base { this.tag(overlayTag + '.OverlayText').alpha = 1; this.tag(overlayTag).setSmooth('alpha', 0, { duration: 5 }); + // Reset progress bar to clear any stale state from a previous install cycle + this.tag(statusProgressTag).reset(); + this._app.isInstalling = true; if (!await installDACApp(this._app, this.tag(statusProgressTag))) { this._app.isInstalling = false; diff --git a/accelerator-home-ui/src/overlays/StatusProgress.js b/accelerator-home-ui/src/overlays/StatusProgress.js index 532c27f..168e3f5 100644 --- a/accelerator-home-ui/src/overlays/StatusProgress.js +++ b/accelerator-home-ui/src/overlays/StatusProgress.js @@ -66,6 +66,7 @@ export default class Progress extends lng.Component { var ww = (this.w - 4) * pc if(pc != 1.0) { this.tag("BackgroundOverlay").alpha=0.6 + this.tag("Label").alpha = 1.0 this.tag("ProgressBar").setSmooth('alpha', 0.7, {duration: .1}) this.tag("Progress").setSmooth('w', ww, { duration: 1 }) } diff --git a/accelerator-home-ui/src/screens/FailAndOkScreen.js b/accelerator-home-ui/src/screens/FailAndOkScreen.js index f638cc0..1ccf42a 100644 --- a/accelerator-home-ui/src/screens/FailAndOkScreen.js +++ b/accelerator-home-ui/src/screens/FailAndOkScreen.js @@ -35,7 +35,7 @@ export default class FailAndOkScreen extends Lightning.Component { this.LOG("notify args: " + JSON.stringify(args)) if (args.title && args.msg) { this.tag('FailScreen.Title').text.text = args.title - this.tag('FailScreen.Message').text.text = Language.translate(args.msg) + this.tag('FailScreen.Message').text.text = args.msg } } diff --git a/accelerator-home-ui/src/views/AppInfoPage.js b/accelerator-home-ui/src/views/AppInfoPage.js index 8af8e3c..982006f 100644 --- a/accelerator-home-ui/src/views/AppInfoPage.js +++ b/accelerator-home-ui/src/views/AppInfoPage.js @@ -299,8 +299,6 @@ export default class AppInfoPage extends Lightning.Component { const result = await uninstallDACApp({ id: appInfo.id, version: appInfo.version, name: appInfo.name }, this); if (result) { console.log(`${appInfo.name} uninstalled successfully`); - // Refresh the list after uninstall - await this._fetchInstalledApps(); return true; } else { console.error(`Failed to uninstall ${appInfo.name}`); @@ -340,19 +338,21 @@ export default class AppInfoPage extends Lightning.Component { /** * Signal handler: user confirmed uninstall */ - $confirmUninstall(appInfo) { + async $confirmUninstall(appInfo) { console.log('Uninstall confirmed for:', appInfo.name); this.tag('UninstallConfirmationOverlay').showUninstalling(); - this._uninstallApp(appInfo).then((success) => { - this._hideUninstallConfirmation(); - if (!success) { - this.widgets.failok.notify({ - title: Language.translate('Uninstall Failed'), - msg: Language.translate('Failed to uninstall') + ` "${appInfo.name}". ` + Language.translate('Please try again later.'), - }); - Router.focusWidget('FailOk'); - } - }); + const success = await this._uninstallApp(appInfo); + // Dismiss overlay first, then refresh list so state transitions don't compete + this._hideUninstallConfirmation(); + if (success) { + await this._fetchInstalledApps(); + } else { + this.widgets.failok.notify({ + title: Language.translate('Uninstall Failed'), + msg: Language.translate('Failed to uninstall') + ` "${appInfo.name}". ` + Language.translate('Please try again later.'), + }); + Router.focusWidget('FailOk'); + } } /** From 3cd38bc48805d598a29e87c5a5ee2f3aa06a17fb Mon Sep 17 00:00:00 2001 From: suryag23 Date: Fri, 20 Mar 2026 14:28:20 +0530 Subject: [PATCH 04/52] Addressed the review comments --- .../src/items/AppCatalogItem.js | 3 ++- accelerator-home-ui/src/views/AppInfoPage.js | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/accelerator-home-ui/src/items/AppCatalogItem.js b/accelerator-home-ui/src/items/AppCatalogItem.js index 25e16da..af4fd2c 100644 --- a/accelerator-home-ui/src/items/AppCatalogItem.js +++ b/accelerator-home-ui/src/items/AppCatalogItem.js @@ -46,11 +46,12 @@ export const DACAppMixin = (Base) => class extends Base { if (this._app.isInstalling) { this._app.isInstalled = success this._app.isInstalling = false + const errorCode = this._app.errorCode ?? -1; if (Object.prototype.hasOwnProperty.call(this._app, "errorCode")) delete this._app.errorCode; this.updateDACStatus(statusProgressTag, overlayTag) if (!success) { this.tag(statusProgressTag).setProgress(1.0, 'Error: ' + msg) - this.fireAncestors('$showInstallError', { name: this._app.name, errorCode: msg || -1 }) + this.fireAncestors('$showInstallError', { name: this._app.name, errorCode: errorCode }) } return true; // Installation operation completed } else if (this._app.isUnInstalling) { diff --git a/accelerator-home-ui/src/views/AppInfoPage.js b/accelerator-home-ui/src/views/AppInfoPage.js index 982006f..50400d7 100644 --- a/accelerator-home-ui/src/views/AppInfoPage.js +++ b/accelerator-home-ui/src/views/AppInfoPage.js @@ -320,19 +320,15 @@ export default class AppInfoPage extends Lightning.Component { } /** - * Hide the uninstall confirmation overlay + * Hide the uninstall confirmation overlay. + * Only handles overlay cleanup; callers are responsible for + * setting the correct page state afterward. */ _hideUninstallConfirmation() { // Reset overlay to its initial state so that Uninstalling.$exit() runs, // stopping the loader animation and restoring hidden UI elements. this.tag('UninstallConfirmationOverlay')._setState('Confirm'); this.tag('UninstallConfirmationOverlay').visible = false; - // Set correct state based on whether apps remain - if (this._appData.length > 0) { - this._setState('AppList'); - } else { - this._setState('EmptyState'); - } } /** @@ -342,11 +338,15 @@ export default class AppInfoPage extends Lightning.Component { console.log('Uninstall confirmed for:', appInfo.name); this.tag('UninstallConfirmationOverlay').showUninstalling(); const success = await this._uninstallApp(appInfo); - // Dismiss overlay first, then refresh list so state transitions don't compete + // Dismiss overlay first, then let _fetchInstalledApps -> _loadAppData + // be the single source of truth for the next page state. this._hideUninstallConfirmation(); if (success) { + // _loadAppData will set AppList or EmptyState based on refreshed data await this._fetchInstalledApps(); } else { + // Uninstall failed — data hasn't changed, restore list focus + this._setState('AppList'); this.widgets.failok.notify({ title: Language.translate('Uninstall Failed'), msg: Language.translate('Failed to uninstall') + ` "${appInfo.name}". ` + Language.translate('Please try again later.'), @@ -361,6 +361,12 @@ export default class AppInfoPage extends Lightning.Component { $cancelUninstall() { console.log('Uninstall cancelled'); this._hideUninstallConfirmation(); + // Data hasn't changed — restore previous page state + if (this._appData.length > 0) { + this._setState('AppList'); + } else { + this._setState('EmptyState'); + } } /** From 7f0c80982737e682a3bd25e5c3eac0fd8c660a6a Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Mon, 16 Mar 2026 23:47:58 -0400 Subject: [PATCH 05/52] RDKEAPPRT-612 :Add dac store details via RFC --- accelerator-home-ui/src/api/AppApi.js | 2 +- accelerator-home-ui/src/api/DACApi.js | 30 +++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/accelerator-home-ui/src/api/AppApi.js b/accelerator-home-ui/src/api/AppApi.js index 4b2bb9b..d3ec733 100644 --- a/accelerator-home-ui/src/api/AppApi.js +++ b/accelerator-home-ui/src/api/AppApi.js @@ -1607,7 +1607,7 @@ export default class AppApi { getRFCConfig(rfcParamsList) { return new Promise((resolve, reject) => { - thunder.call('org.rdk.System', 'getRFCConfig', rfcParamsList).then(result => { + thunder.call('org.rdk.System', 'getRFCConfig',{rfcList:[rfcParamsList]}).then(result => { if (result.success) { resolve(result) } else { diff --git a/accelerator-home-ui/src/api/DACApi.js b/accelerator-home-ui/src/api/DACApi.js index d03afbf..423cb7e 100644 --- a/accelerator-home-ui/src/api/DACApi.js +++ b/accelerator-home-ui/src/api/DACApi.js @@ -20,6 +20,7 @@ import DownloadManager from './DownloadManagerApi'; import PackageManager from './PackageManagerApi'; import AppManager from './AppManagerApi'; +import AppApi from './AppApi'; import AppController from '../AppController'; import { ThunderError } from './ThunderError'; import { Metrics } from '@firebolt-js/sdk' @@ -73,11 +74,32 @@ let storeConfig = null; async function getStoreConfig() { if (!storeConfig) { - const config = await PackageManager.get().configuration(); - if (typeof config?.configUrl !== "string") { - throw new Error("Invalid config: " + JSON.stringify(config)); + const appApi = new AppApi(); + const rfcKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; + let resolvedConfigUrl = null; + try { + const result = await appApi.getRFCConfig(rfcKey); + const rfcUrl = result?.RFCConfig?.[rfcKey]; + console.log("config URL from RFC :", rfcUrl); + if (typeof rfcUrl == "string" && rfcUrl.trim().length > 0) { + resolvedConfigUrl = rfcUrl.trim(); + } else { + console.warn("RFC URL empty or invalid; will fall back to PackageManager."); + } + } catch (err) { + console.warn("getRFCConfig failed; will fall back to PackageManager.", err); + } + + if (!resolvedConfigUrl) { + const config = await PackageManager.get().configuration(); + if (typeof config?.configUrl !== "string") { + throw new Error("Invalid config: " + JSON.stringify(config)); + } else { + resolvedConfigUrl = config?.configUrl; + console.log("config URL from packagemanager :", resolvedConfigUrl); + } } - const fetchResponse = await fetch(config.configUrl); + const fetchResponse = await fetch(resolvedConfigUrl); if (!fetchResponse.ok) { throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); } From 6f3b3a2b3f08d0fa6cecd29af3b87dcac41eb90f Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Mon, 16 Mar 2026 23:55:23 -0400 Subject: [PATCH 06/52] RDKEAPPRT-612:dac store url via RFC --- accelerator-home-ui/src/api/DACApi.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/accelerator-home-ui/src/api/DACApi.js b/accelerator-home-ui/src/api/DACApi.js index 423cb7e..9dcd068 100644 --- a/accelerator-home-ui/src/api/DACApi.js +++ b/accelerator-home-ui/src/api/DACApi.js @@ -80,7 +80,6 @@ async function getStoreConfig() { try { const result = await appApi.getRFCConfig(rfcKey); const rfcUrl = result?.RFCConfig?.[rfcKey]; - console.log("config URL from RFC :", rfcUrl); if (typeof rfcUrl == "string" && rfcUrl.trim().length > 0) { resolvedConfigUrl = rfcUrl.trim(); } else { @@ -96,7 +95,6 @@ async function getStoreConfig() { throw new Error("Invalid config: " + JSON.stringify(config)); } else { resolvedConfigUrl = config?.configUrl; - console.log("config URL from packagemanager :", resolvedConfigUrl); } } const fetchResponse = await fetch(resolvedConfigUrl); From 0acb616126a19adc4fdb005589261464b8c0fcb1 Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Thu, 19 Mar 2026 17:46:17 -0400 Subject: [PATCH 07/52] RDKEAPPRT-612 : Get DAC store details via RFC --- accelerator-home-ui/src/api/AppApi.js | 2 +- accelerator-home-ui/src/api/DACApi.js | 62 ++++++++++++++++++--------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/accelerator-home-ui/src/api/AppApi.js b/accelerator-home-ui/src/api/AppApi.js index d3ec733..c1d5f45 100644 --- a/accelerator-home-ui/src/api/AppApi.js +++ b/accelerator-home-ui/src/api/AppApi.js @@ -1607,7 +1607,7 @@ export default class AppApi { getRFCConfig(rfcParamsList) { return new Promise((resolve, reject) => { - thunder.call('org.rdk.System', 'getRFCConfig',{rfcList:[rfcParamsList]}).then(result => { + thunder.call('org.rdk.System', 'getRFCConfig',{"rfcList":[rfcParamsList]}).then(result => { if (result.success) { resolve(result) } else { diff --git a/accelerator-home-ui/src/api/DACApi.js b/accelerator-home-ui/src/api/DACApi.js index 9dcd068..3ab198c 100644 --- a/accelerator-home-ui/src/api/DACApi.js +++ b/accelerator-home-ui/src/api/DACApi.js @@ -39,6 +39,8 @@ const APP_DETAILS_KEY = "refui.details"; const APP_DEFAULT_ARCH = "arm"; +const APP_STORE_RFC_KEY = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; + function makeLogMessage(call, err) { return err.toString() + " <=> " + call; } @@ -72,31 +74,51 @@ class OperationLock { let packageLock = new OperationLock(); let storeConfig = null; -async function getStoreConfig() { - if (!storeConfig) { +async function getConfigUrlFromRFC() { + try { const appApi = new AppApi(); - const rfcKey = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; - let resolvedConfigUrl = null; - try { - const result = await appApi.getRFCConfig(rfcKey); - const rfcUrl = result?.RFCConfig?.[rfcKey]; - if (typeof rfcUrl == "string" && rfcUrl.trim().length > 0) { - resolvedConfigUrl = rfcUrl.trim(); - } else { - console.warn("RFC URL empty or invalid; will fall back to PackageManager."); - } - } catch (err) { - console.warn("getRFCConfig failed; will fall back to PackageManager.", err); + console.log("Resolving DAC Store URL from RFC "); + const result = await appApi.getRFCConfig(APP_STORE_RFC_KEY); + const rfcUrl = result?.RFCConfig?.[APP_STORE_RFC_KEY]; + if (typeof rfcUrl === "string" && rfcUrl.trim().length > 0) { + const resolvedConfigUrl = rfcUrl.trim(); + console.log("Resolved DAC Store URL from RFC "); + return resolvedConfigUrl; + } + console.warn("DAC Store RFC URL empty or invalid"); + return null; + } catch (err) { + console.error("Failed to get DAC Store URL from RFC", err); + return null; + } +} + +async function getConfigUrlFromPackageManager() { + try { + console.log("Resolving DAC Store URL from PackageManager..."); + const config = await PackageManager.get().configuration(); + console.log("Resolved DAC Store URL from PackageManager: "); + if (typeof config?.configUrl !== "string" || config.configUrl.trim().length === 0) { + throw new Error("Invalid config: " + JSON.stringify(config)); } + return config.configUrl.trim(); + } catch (err) { + console.error("Failed to resolve DAC Store URL from PackageManager", err); + throw err; + } +} + +async function getStoreConfig() { + if (!storeConfig) { + console.log("Resolving DAC Store config URL..."); + let resolvedConfigUrl = await getConfigUrlFromRFC(); + if (!resolvedConfigUrl) { - const config = await PackageManager.get().configuration(); - if (typeof config?.configUrl !== "string") { - throw new Error("Invalid config: " + JSON.stringify(config)); - } else { - resolvedConfigUrl = config?.configUrl; - } + resolvedConfigUrl = await getConfigUrlFromPackageManager(); } + + console.log("Resolved DAC Store config URL "); const fetchResponse = await fetch(resolvedConfigUrl); if (!fetchResponse.ok) { throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); From 19c9dca069e4e0b025b2c314ad02c362e7e9e85e Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:53:00 +0530 Subject: [PATCH 08/52] RDKEAPPRT-645 Add default error overlay when user tries to enter VOD content (#162) * RDKEAPPRT-645 Add default error overlay when user tries to enter VOD content * Addressed the review comments --- accelerator-home-ui/src/views/MainView.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/accelerator-home-ui/src/views/MainView.js b/accelerator-home-ui/src/views/MainView.js index f31a73e..b70b891 100644 --- a/accelerator-home-ui/src/views/MainView.js +++ b/accelerator-home-ui/src/views/MainView.js @@ -1066,14 +1066,10 @@ export default class MainView extends Lightning.Component { Router.focusWidget('Menu') } } - async _handleEnter() { + _handleEnter() { if (Router.isNavigating()) return; - this.LOG("MainView: internetConnectivity " + JSON.stringify(GLOBALS.IsConnectedToInternet)); - let params ={url: this.tag('TVShows').items[this.tag('TVShows').index].data.uri, - } - if (GLOBALS.IsConnectedToInternet) { - Router.navigate("player",params) - } + this.widgets.failok.notify({ title: Language.translate('Not Supported'), msg: Language.translate('VOD feature is not supported.') }) + Router.focusWidget('FailOk') } $exit() { this.tag('Text3').text.fontStyle = 'normal' From b9dfca048869fb42db10c0d6e64c992a8c7de94d Mon Sep 17 00:00:00 2001 From: suryag23 Date: Wed, 25 Mar 2026 14:56:13 +0530 Subject: [PATCH 09/52] RDKEAPPRT-646 Create the Username, Password page and add it inside the settings route --- .../src/routes/networkRoutes.js | 6 + .../src/screens/DacStoreLoginComponent.js | 369 ++++++++++++++++++ .../src/screens/SettingsScreen.js | 61 ++- 3 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 accelerator-home-ui/src/screens/DacStoreLoginComponent.js diff --git a/accelerator-home-ui/src/routes/networkRoutes.js b/accelerator-home-ui/src/routes/networkRoutes.js index 1f8e091..15386bb 100644 --- a/accelerator-home-ui/src/routes/networkRoutes.js +++ b/accelerator-home-ui/src/routes/networkRoutes.js @@ -26,6 +26,7 @@ import NetworkInterfaceScreen from "../screens/OtherSettingsScreens/NetworkInter import WifiPairingScreen from "../screens/WiFiPairingScreen" import WiFiScreen from "../screens/WifiScreen" import RCVolumeInfoScreen from '../screens/RcInformationScreen' +import DacStoreLoginComponent from '../screens/DacStoreLoginComponent' const networkRoutes = [ { @@ -72,6 +73,11 @@ const networkRoutes = [ path: 'settings/bluetooth/RCVolumeInfoScreen', component: RCVolumeInfoScreen, widgets: ["Menu",'Volume', "Fail","AppCarousel"] + }, + { + path: 'settings/dacstore', + component: DacStoreLoginComponent, + widgets: ['Volume', 'AppCarousel'] } ] diff --git a/accelerator-home-ui/src/screens/DacStoreLoginComponent.js b/accelerator-home-ui/src/screens/DacStoreLoginComponent.js new file mode 100644 index 0000000..e6157b3 --- /dev/null +++ b/accelerator-home-ui/src/screens/DacStoreLoginComponent.js @@ -0,0 +1,369 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ +import { Language, Lightning, Router, Utils } from '@lightningjs/sdk' +import { CONFIG } from '../Config/Config'; +import { Keyboard } from '../ui-components/index' +import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' +import PasswordSwitch from './PasswordSwitch'; + +export default class DacStoreLoginComponent extends Lightning.Component { + + constructor(...args) { + super(...args); + this.INFO = console.info; + this.LOG = console.log; + this.ERR = console.error; + this.WARN = console.warn; + } + + pageTransition() { + return 'left' + } + + _active() { + this.hidePasswd = true + this.star = "" + this.tag("Keyboard").visible = false + } + + handleDone() { + this.tag("Keyboard").visible = false + if (!this.textCollection['EnterUsername']) { + this._setState("EnterUsername"); + } + else if (!this.textCollection['EnterPassword']) { + this._setState("EnterPassword"); + } + else { + this.LOG('DAC Store Login - Username: ' + this.textCollection['EnterUsername']) + } + } + + static _template() { + return { + Background: { + w: 1920, + h: 1080, + rect: true, + color: 0xCC000000, + }, + Text: { + x: 758, + y: 70, + text: { + text: Language.translate("Connect to the Application Catalog"), + fontFace: CONFIG.language.font, + fontSize: 35, + textColor: CONFIG.theme.hex, + }, + }, + BorderTop: { + x: 190, y: 130, w: 1488, h: 2, rect: true, + }, + Username: { + x: 190, + y: 176, + text: { + text: Language.translate("Username") + ": ", + fontFace: CONFIG.language.font, + fontSize: 25, + }, + }, + UsernameBox: { + x: 400, + y: 160, + texture: Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + }, + UsernameText: { + x: 420, + y: 170, + zIndex: 2, + text: { + text: '', + fontSize: 25, + fontFace: CONFIG.language.font, + textColor: 0xffffffff, + wordWrapWidth: 1300, + wordWrap: false, + textOverflow: 'ellipsis', + }, + }, + Password: { + x: 190, + y: 246, + text: { + text: Language.translate("Password") + ":", + fontFace: CONFIG.language.font, + fontSize: 25, + }, + }, + PasswordBox: { + x: 400, + y: 230, + texture: Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + }, + Pwd: { + x: 420, + y: 240, + zIndex: 2, + text: { + text: '', + fontSize: 25, + fontFace: CONFIG.language.font, + textColor: 0xffffffff, + wordWrapWidth: 1300, + wordWrap: false, + textOverflow: 'ellipsis', + }, + }, + BorderBottom: { + x: 190, y: 326, w: 1488, h: 2, rect: true, + }, + ExitButton: { + x: 960, + y: 350, + mountX: 0.5, + w: 200, + h: 50, + rect: true, + color: 0xff444444, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 10 }, + ExitLabel: { + x: 100, + y: 25, + mount: 0.5, + text: { + text: Language.translate('Exit'), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xffffffff, + }, + }, + }, + Keyboard: { + y: 420, + x: 400, + type: Keyboard, + visible: false, + zIndex: 2, + formats: KEYBOARD_FORMATS.qwerty + }, + PasswrdSwitch: { + h: 45, + w: 66.9, + x: 1642, + y: 260, + zIndex: 2, + type: PasswordSwitch, + mount: 0.5, + visible: true + }, + ShowPassword: { + x: 1365, + y: 242, + w: 300, + h: 75, + zIndex: 2, + text: { text: Language.translate('Show Password'), fontSize: 25, fontFace: CONFIG.language.font, textColor: 0xffffffff, textAlign: 'left' }, + visible: true + } + } + } + + _focus() { + this._setState('EnterUsername'); + this.textCollection = { 'EnterUsername': '', 'EnterPassword': '' } + this.tag('Pwd').text.text = Language.translate("Press OK to enter Password"); + this.tag("UsernameText").text.text = Language.translate("Press OK to enter Username"); + this.tag('UsernameText').text.textColor = 0xff808080 + this.tag('Pwd').text.textColor = 0xff808080 + } + + encrypt() { + if (this.prevState === "EnterPassword" && this.hidePasswd) + return true + else + return false + } + + _updateText(txt) { + this.tag("Pwd").text.text = txt; + } + + _handleBack() { + if (!Router.isNavigating()) { + Router.back() + } + } + + static _states() { + return [ + class EnterUsername extends this { + $enter() { + this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + } + _handleDown() { + this._setState("EnterPassword"); + } + _handleEnter() { + this._setState('Keyboard') + this.tag('UsernameText').text.text = this.textCollection['EnterUsername'] + this.tag('UsernameText').text.textColor = 0xffffffff + this.tag("Keyboard").visible = true + } + $exit() { + this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + } + }, + class EnterPassword extends this { + $enter() { + this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + } + _handleUp() { + this._setState("EnterUsername"); + } + _handleDown() { + this._setState("ExitButton"); + } + _handleRight() { + this._setState("PasswordSwitchState") + } + _handleEnter() { + this.tag("Keyboard").visible = true + this._setState('Keyboard') + this.tag('Pwd').text.text = this.hidePasswd ? this.star : this.textCollection['EnterPassword'] + this.tag('Pwd').text.textColor = 0xffffffff + } + $exit() { + this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false); + } + }, + class PasswordSwitchState extends this { + $enter() { + this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + this.tag('ShowPassword').text.textColor = CONFIG.theme.hex + } + _handleDown() { + this._setState("Keyboard"); + } + _handleUp() { + this._setState("EnterUsername"); + } + _handleLeft() { + this._setState("EnterPassword"); + } + _getFocused() { + return this.tag('PasswrdSwitch'); + } + + $handleEnter(bool) { + if (bool) { + this._updateText(this.textCollection['EnterPassword']) + this.hidePasswd = false; + } + else { + this._updateText(this.star); + this.hidePasswd = true; + } + this.isOn = bool; + } + + $exit() { + this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + this.tag('ShowPassword').text.textColor = 0xffffffff + } + }, + class ExitButton extends this { + $enter() { + this.tag('ExitButton').color = CONFIG.theme.hex + } + $exit() { + this.tag('ExitButton').color = 0xff444444 + } + _handleUp() { + this._setState('EnterPassword') + } + _handleDown() { + this._setState('EnterUsername') + } + _handleEnter() { + if (!Router.isNavigating()) { + Router.back() + } + } + }, + class Keyboard extends this { + $enter(state) { + this.prevState = state.prevState + if (this.prevState === 'EnterUsername') { + this.element = 'UsernameText' + } + if (this.prevState === 'EnterPassword') { + this.element = 'Pwd' + } + } + _getFocused() { + return this.tag('Keyboard') + } + + $onSoftKey({ key }) { + if (this.prevState === 'PasswordSwitchState') { + this.prevState = "EnterPassword" + } + this.LOG("Prev state: " + JSON.stringify(this.prevState)) + if (key === 'Done') { + this.handleDone(); + } else if (key === 'Clear') { + this.textCollection[this.prevState] = this.textCollection[this.prevState].substring(0, this.textCollection[this.prevState].length - 1); + this.star = (this.prevState === "EnterPassword") ? this.star.substring(0, this.star.length - 1) : this.star + this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; + } else if (key === '#@!' || key === 'abc' || key === 'áöû' || key === 'shift') { + this.LOG('no saving') + } else if (key === 'Space') { + this.textCollection[this.prevState] += ' ' + this.star += (this.prevState === "EnterPassword") ? '\u25CF' : this.star + this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; + } else if (key === 'Delete') { + this.textCollection[this.prevState] = '' + this.star = (this.prevState === "EnterPassword") ? '' : this.star + this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; + } else { + this.textCollection[this.prevState] += key + this.star += (this.prevState === "EnterPassword") ? '\u25CF' : this.star + this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; + } + } + _handleUp() { + this._setState(this.prevState) + } + + _handleBack() { + this._setState(this.prevState) + } + } + ] + } + + _init() { + this.star = '' + this.textCollection = { 'EnterUsername': '', 'EnterPassword': '' } + this.tag("Pwd").text.text = this.textCollection['EnterPassword'] + this.tag("UsernameText").text.text = this.textCollection['EnterUsername'] + } +} diff --git a/accelerator-home-ui/src/screens/SettingsScreen.js b/accelerator-home-ui/src/screens/SettingsScreen.js index 9659e8f..3bd8f47 100644 --- a/accelerator-home-ui/src/screens/SettingsScreen.js +++ b/accelerator-home-ui/src/screens/SettingsScreen.js @@ -79,9 +79,33 @@ export default class SettingsScreen extends Lightning.Component { src: Utils.asset('images/settings/Arrow.png'), }, }, - Bluetooth: { + DacStore: { y: 90, type: SettingsMainItem, + Title: { + x: 10, + y: 45, + mountY: 0.5, + text: { + text: Language.translate('Connect to the Application Catalog'), + textColor: COLORS.titleColor, + fontFace: CONFIG.language.font, + fontSize: 25, + } + }, + Button: { + h: 45, + w: 45, + x: 1600, + mountX: 1, + y: 45, + mountY: 0.5, + src: Utils.asset('images/settings/Arrow.png'), + }, + }, + Bluetooth: { + y: 180, + type: SettingsMainItem, Title: { x: 10, y: 45, @@ -104,7 +128,7 @@ export default class SettingsScreen extends Lightning.Component { }, }, Video: { - y: 180, + y: 270, type: SettingsMainItem, Title: { x: 10, @@ -128,7 +152,7 @@ export default class SettingsScreen extends Lightning.Component { }, }, Audio: { - y: 270, + y: 360, type: SettingsMainItem, Title: { x: 10, @@ -152,7 +176,7 @@ export default class SettingsScreen extends Lightning.Component { }, }, OtherSettings: { - y: 360, + y: 450, type: SettingsMainItem, Title: { x: 10, @@ -177,7 +201,7 @@ export default class SettingsScreen extends Lightning.Component { }, NFRStatus: { - y: 450, + y: 540, type: SettingsMainItem, Title: { x: 10, @@ -204,7 +228,7 @@ export default class SettingsScreen extends Lightning.Component { DTVSettings: { alpha: 0.3, - y: 630, + y: 720, type: SettingsMainItem, Title: { x: 10, @@ -229,7 +253,7 @@ export default class SettingsScreen extends Lightning.Component { }, VoiceRemoteControl: { - y: 540, + y: 630, type: SettingsMainItem, Title: { x: 10, @@ -300,7 +324,7 @@ export default class SettingsScreen extends Lightning.Component { this.tag('NetworkConfiguration')._unfocus() } _handleDown() { - this._setState('Bluetooth') + this._setState('DacStore') } _handleEnter() { if (!Router.isNavigating()) { @@ -308,6 +332,25 @@ export default class SettingsScreen extends Lightning.Component { } } }, + class DacStore extends this { + $enter() { + this.tag('DacStore')._focus() + } + $exit() { + this.tag('DacStore')._unfocus() + } + _handleUp() { + this._setState('NetworkConfiguration') + } + _handleDown() { + this._setState('Bluetooth') + } + _handleEnter() { + if (!Router.isNavigating()) { + Router.navigate('settings/dacstore') + } + } + }, class Bluetooth extends this { $enter() { this.tag('Bluetooth')._focus() @@ -316,7 +359,7 @@ export default class SettingsScreen extends Lightning.Component { this.tag('Bluetooth')._unfocus() } _handleUp() { - this._setState('NetworkConfiguration') + this._setState('DacStore') } _handleDown() { this._setState('Video') From 73208ddefab21ae3ab533d33ab3443c6bf7d4547 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Wed, 25 Mar 2026 15:01:48 +0530 Subject: [PATCH 10/52] renamed the file --- accelerator-home-ui/src/routes/networkRoutes.js | 4 ++-- ...acStoreLoginComponent.js => AppCatalogueLogicComponent.js} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename accelerator-home-ui/src/screens/{DacStoreLoginComponent.js => AppCatalogueLogicComponent.js} (99%) diff --git a/accelerator-home-ui/src/routes/networkRoutes.js b/accelerator-home-ui/src/routes/networkRoutes.js index 15386bb..410144e 100644 --- a/accelerator-home-ui/src/routes/networkRoutes.js +++ b/accelerator-home-ui/src/routes/networkRoutes.js @@ -26,7 +26,7 @@ import NetworkInterfaceScreen from "../screens/OtherSettingsScreens/NetworkInter import WifiPairingScreen from "../screens/WiFiPairingScreen" import WiFiScreen from "../screens/WifiScreen" import RCVolumeInfoScreen from '../screens/RcInformationScreen' -import DacStoreLoginComponent from '../screens/DacStoreLoginComponent' +import AppCatalogueLogicComponent from '../screens/AppCatalogueLogicComponent' const networkRoutes = [ { @@ -76,7 +76,7 @@ const networkRoutes = [ }, { path: 'settings/dacstore', - component: DacStoreLoginComponent, + component: AppCatalogueLogicComponent, widgets: ['Volume', 'AppCarousel'] } ] diff --git a/accelerator-home-ui/src/screens/DacStoreLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js similarity index 99% rename from accelerator-home-ui/src/screens/DacStoreLoginComponent.js rename to accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js index e6157b3..7d98466 100644 --- a/accelerator-home-ui/src/screens/DacStoreLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js @@ -22,7 +22,7 @@ import { Keyboard } from '../ui-components/index' import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' import PasswordSwitch from './PasswordSwitch'; -export default class DacStoreLoginComponent extends Lightning.Component { +export default class AppCatalogueLogicComponent extends Lightning.Component { constructor(...args) { super(...args); From 1af047bf2cd7f24a3afade9dfa5d66e4d48d2c31 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Wed, 25 Mar 2026 15:08:11 +0530 Subject: [PATCH 11/52] Update the filename correctly --- accelerator-home-ui/src/routes/networkRoutes.js | 6 +++--- ...talogueLogicComponent.js => AppCatalogLoginComponent.js} | 2 +- accelerator-home-ui/src/screens/SettingsScreen.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename accelerator-home-ui/src/screens/{AppCatalogueLogicComponent.js => AppCatalogLoginComponent.js} (99%) diff --git a/accelerator-home-ui/src/routes/networkRoutes.js b/accelerator-home-ui/src/routes/networkRoutes.js index 410144e..a262b47 100644 --- a/accelerator-home-ui/src/routes/networkRoutes.js +++ b/accelerator-home-ui/src/routes/networkRoutes.js @@ -26,7 +26,7 @@ import NetworkInterfaceScreen from "../screens/OtherSettingsScreens/NetworkInter import WifiPairingScreen from "../screens/WiFiPairingScreen" import WiFiScreen from "../screens/WifiScreen" import RCVolumeInfoScreen from '../screens/RcInformationScreen' -import AppCatalogueLogicComponent from '../screens/AppCatalogueLogicComponent' +import AppCatalogLoginComponent from '../screens/AppCatalogLoginComponent' const networkRoutes = [ { @@ -75,8 +75,8 @@ const networkRoutes = [ widgets: ["Menu",'Volume', "Fail","AppCarousel"] }, { - path: 'settings/dacstore', - component: AppCatalogueLogicComponent, + path: 'settings/appcataloglogin', + component: AppCatalogLoginComponent, widgets: ['Volume', 'AppCarousel'] } ] diff --git a/accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js similarity index 99% rename from accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js rename to accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index 7d98466..36fa871 100644 --- a/accelerator-home-ui/src/screens/AppCatalogueLogicComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -22,7 +22,7 @@ import { Keyboard } from '../ui-components/index' import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' import PasswordSwitch from './PasswordSwitch'; -export default class AppCatalogueLogicComponent extends Lightning.Component { +export default class AppCatalogLoginComponent extends Lightning.Component { constructor(...args) { super(...args); diff --git a/accelerator-home-ui/src/screens/SettingsScreen.js b/accelerator-home-ui/src/screens/SettingsScreen.js index 3bd8f47..fe45b72 100644 --- a/accelerator-home-ui/src/screens/SettingsScreen.js +++ b/accelerator-home-ui/src/screens/SettingsScreen.js @@ -347,7 +347,7 @@ export default class SettingsScreen extends Lightning.Component { } _handleEnter() { if (!Router.isNavigating()) { - Router.navigate('settings/dacstore') + Router.navigate('settings/appcataloglogin') } } }, From e57704cebb8b492a4eca9b7e702d8748ab6efcec Mon Sep 17 00:00:00 2001 From: suryag23 Date: Wed, 25 Mar 2026 16:13:06 +0530 Subject: [PATCH 12/52] Addressed the review comments --- .../src/screens/AppCatalogLoginComponent.js | 10 +++++----- accelerator-home-ui/src/screens/SettingsScreen.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index 36fa871..509f3dc 100644 --- a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -import { Language, Lightning, Router, Utils } from '@lightningjs/sdk' +import { Language, Lightning, Router } from '@lightningjs/sdk' import { CONFIG } from '../Config/Config'; import { Keyboard } from '../ui-components/index' import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' @@ -51,7 +51,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this._setState("EnterPassword"); } else { - this.LOG('DAC Store Login - Username: ' + this.textCollection['EnterUsername']) + this.LOG('App Catalog Login - credentials submitted') } } @@ -260,7 +260,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.tag('ShowPassword').text.textColor = CONFIG.theme.hex } _handleDown() { - this._setState("Keyboard"); + this._setState("ExitButton"); } _handleUp() { this._setState("EnterUsername"); @@ -337,7 +337,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.LOG('no saving') } else if (key === 'Space') { this.textCollection[this.prevState] += ' ' - this.star += (this.prevState === "EnterPassword") ? '\u25CF' : this.star + this.star += (this.prevState === "EnterPassword") ? '\u25CF' : '' this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; } else if (key === 'Delete') { this.textCollection[this.prevState] = '' @@ -345,7 +345,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; } else { this.textCollection[this.prevState] += key - this.star += (this.prevState === "EnterPassword") ? '\u25CF' : this.star + this.star += (this.prevState === "EnterPassword") ? '\u25CF' : '' this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; } } diff --git a/accelerator-home-ui/src/screens/SettingsScreen.js b/accelerator-home-ui/src/screens/SettingsScreen.js index fe45b72..207e8f3 100644 --- a/accelerator-home-ui/src/screens/SettingsScreen.js +++ b/accelerator-home-ui/src/screens/SettingsScreen.js @@ -487,7 +487,7 @@ export default class SettingsScreen extends Lightning.Component { this.tag('DTVSettings')._unfocus() } _handleUp() { - this._setState('NFRStatus') + this._setState('VoiceRemoteControl') } _handleEnter() { if (this.dtvPlugin) { From 361a48e22df2aedc29426debc830812c2297d40c Mon Sep 17 00:00:00 2001 From: suryag23 Date: Wed, 25 Mar 2026 16:48:19 +0530 Subject: [PATCH 13/52] Reneamed the DAC instance to Applicationcataloguelogin --- accelerator-home-ui/src/screens/SettingsScreen.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accelerator-home-ui/src/screens/SettingsScreen.js b/accelerator-home-ui/src/screens/SettingsScreen.js index 207e8f3..34b766f 100644 --- a/accelerator-home-ui/src/screens/SettingsScreen.js +++ b/accelerator-home-ui/src/screens/SettingsScreen.js @@ -79,7 +79,7 @@ export default class SettingsScreen extends Lightning.Component { src: Utils.asset('images/settings/Arrow.png'), }, }, - DacStore: { + ApplicationCatalogueLogin: { y: 90, type: SettingsMainItem, Title: { @@ -324,7 +324,7 @@ export default class SettingsScreen extends Lightning.Component { this.tag('NetworkConfiguration')._unfocus() } _handleDown() { - this._setState('DacStore') + this._setState('ApplicationCatalogueLogin') } _handleEnter() { if (!Router.isNavigating()) { @@ -332,12 +332,12 @@ export default class SettingsScreen extends Lightning.Component { } } }, - class DacStore extends this { + class ApplicationCatalogueLogin extends this { $enter() { - this.tag('DacStore')._focus() + this.tag('ApplicationCatalogueLogin')._focus() } $exit() { - this.tag('DacStore')._unfocus() + this.tag('ApplicationCatalogueLogin')._unfocus() } _handleUp() { this._setState('NetworkConfiguration') @@ -359,7 +359,7 @@ export default class SettingsScreen extends Lightning.Component { this.tag('Bluetooth')._unfocus() } _handleUp() { - this._setState('DacStore') + this._setState('ApplicationCatalogueLogin') } _handleDown() { this._setState('Video') From 2605f2045f74e2e2386f25fb8c55af64f8aea1b0 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 26 Mar 2026 16:41:56 +0530 Subject: [PATCH 14/52] RDKEAPPRT-621,606,648,644 --- accelerator-home-ui/src/App.js | 14 ++++++++++- .../OtherSettings/LanguageScreenOverlay.js | 25 +------------------ .../OtherSettingsScreens/LanguageScreen.js | 22 +--------------- .../screens/SplashScreens/LanguageScreen.js | 23 +---------------- accelerator-home-ui/src/views/AppStore.js | 1 + 5 files changed, 17 insertions(+), 68 deletions(-) diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 86b06ea..dce4069 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -1676,6 +1676,10 @@ export default class App extends Router.App { } _PowerStateHandlingWhileReboot() { + if (this._oldPowerStateWhileReboot === PowerState.POWER_STATE_STANDBY) { + this.LOG("_PowerStateHandlingWhileReboot: oldPowerStateWhileReboot is STANDBY, setting it to ON"); + this._oldPowerStateWhileReboot = PowerState.POWER_STATE_ON; + } this.LOG("_PowerStateHandlingWhileReboot: this._oldPowerStateWhileReboot , " + JSON.stringify(this._oldPowerStateWhileReboot) + " this._powerStateWhileReboot, " + JSON.stringify(this._powerStateWhileReboot) + " "); if (this._oldPowerStateWhileReboot != this._powerStateWhileReboot) { this.LOG("_PowerStateHandlingWhileReboot: old power state is not equal to powerstate while reboot " + JSON.stringify(this._oldPowerStateWhileReboot) + " " + JSON.stringify(this._powerStateWhileReboot)); @@ -2138,7 +2142,15 @@ export default class App extends Router.App { appApi.exitApp(currentApp); //will suspend/destroy the app depending on the setting. } Router.navigate('menu'); - } else if (notification.newState === "ON" && notification.currentState !== "ON") { + } + else if(notification.newState === PowerState.POWER_STATE_LIGHT_SLEEP && notification.currentState === PowerState.POWER_STATE_DEEP_SLEEP){ + appApi.setPowerState("ON").then(res => { + this.LOG("Device woke up from DEEP_SLEEP to LIGHT_SLEEP . setPowerState result: " + JSON.stringify(res)) + }).catch(err => { + this.ERR("Failed to set power state to ON when device woke up from DEEP_SLEEP to LIGHT_SLEEP. Error: " + JSON.stringify(err)) + }) + } + else if (notification.newState === "ON" && notification.currentState !== "ON") { //TURNING ON THE DEVICE Storage.remove(SLEEP_STATE) } diff --git a/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js b/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js index 19bcf30..a4bee32 100644 --- a/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js +++ b/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js @@ -74,17 +74,6 @@ export default class LanguageScreen extends Lightning.Component { item: item, } }) - RDKShellApis.destroy(loader).catch(err => { - this.ERR("LanguageScreenOverlay: Error destroy loader: " + JSON.stringify(err)) - }); - RDKShellApis.setVisibility(GLOBALS.selfClientName, true); - RDKShellApis.moveToFront(GLOBALS.selfClientName); - RDKShellApis.setFocus(GLOBALS.selfClientName).then(() => { - this.LOG('LanguageScreenOverlay: ResidentApp moveToFront Success'); - }).catch(err => { - this.ERR('LanguageScreenOverlay: Error: ' + JSON.stringify(err)); - Metrics.error(Metrics.ErrorType.OTHER, "PluginError", "Thunder RDKShell Failed to moveToFront " + JSON.stringify(err), false, null) - }); } _focus() { @@ -109,20 +98,8 @@ export default class LanguageScreen extends Lightning.Component { //need to verify if (Language.get() !== availableLanguages[this._Languages.tag('List').index]) { let updatedLanguage = availableLanguageCodes[availableLanguages[this._Languages.tag('List').index]] - if ("ResidentApp" !== GLOBALS.selfClientName) { - FireBoltApi.get().localization.setlanguage(availableLanguages[this._Languages.tag('List').index]).then(res => this.LOG("language set successfully")) - } else { - appApi.setUILanguage(updatedLanguage) - } + appApi.setUILanguage(updatedLanguage) localStorage.setItem('Language',availableLanguages[this._Languages.tag('List').index]) - let path = location.pathname.split('index.html')[0] - let url = path.slice(-1) === '/' ? "static/loaderApp/index.html" : "/static/loaderApp/index.html" - let notification_url = location.origin + path + url - this.LOG(notification_url) - appApi.launchResident(notification_url, loader).catch(err => { - this.ERR("Error launchResident: " + JSON.stringify(err)) - }) - RDKShellApis.setVisibility(GLOBALS.selfClientName, false) location.reload(); } } diff --git a/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js b/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js index ed150d5..8cfeeab 100644 --- a/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js +++ b/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js @@ -94,17 +94,6 @@ export default class LanguageScreen extends Lightning.Component { item: item, } }) - appApi.deactivateResidentApp(loader) - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setFocus(GLOBALS.selfClientName).then(result => { - this.LOG('LanguageScreen: ResidentApp moveToFront Success'); - RDKShellApis.getVisibility(GLOBALS.selfClientName).then(visible => { - if (!visible) RDKShellApis.setVisibility(GLOBALS.selfClientName, true); - }) - }).catch(err => { - this.ERR('LanguageScreen: Error' + JSON.stringify(err)); - Metrics.error(Metrics.ErrorType.OTHER, "AppLangugaeError", 'Thunder RDKShell setFocus Error' + JSON.stringify(err), false, null) - }); } _focus() { @@ -146,17 +135,8 @@ export default class LanguageScreen extends Lightning.Component { } }) } - if ("ResidentApp" === GLOBALS.selfClientName) { - appApi.setUILanguage(updatedLanguage) - } else { - FireBoltApi.get().localization.setlanguage(availableLanguages[this._Languages.tag('List').index]).then(res => this.LOG("sucess language set ::::" + JSON.stringify(res))) - } + appApi.setUILanguage(updatedLanguage) localStorage.setItem('Language',availableLanguages[this._Languages.tag('List').index]) - let path = location.pathname.split('index.html')[0] - let url = path.slice(-1) === '/' ? "static/loaderApp/index.html" : "/static/loaderApp/index.html" - let notification_url = location.origin + path + url - appApi.launchResident(notification_url, loader).catch(err => {this.ERR("error while launching loader url in resident app" + JSON.stringify(err)) }) - RDKShellApis.setVisibility(GLOBALS.selfClientName, false) location.reload(); } } diff --git a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js index 697d63b..b1c0726 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js @@ -122,17 +122,6 @@ export default class LanguageScreen extends Lightning.Component { } }) - appApi.deactivateResidentApp(loader) - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setFocus(GLOBALS.selfClientName).then(result => { - this.LOG('LanguageScreen: ResidentApp moveToFront Success') - RDKShellApis.getVisibility(GLOBALS.selfClientName).then(visible => { - if (!visible) RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - }) - }).catch(err => { - this.ERR('LanguageScreen: Error' + JSON.stringify(err)) - Metrics.error(Metrics.ErrorType.OTHER, "AppLangugaeError", 'Thunder RDKShell setFocus Error' + JSON.stringify(err), false, null) - }); } pageTransition() { @@ -148,11 +137,7 @@ export default class LanguageScreen extends Lightning.Component { } updateUILanguage(index) { - if ("ResidentApp" === GLOBALS.selfClientName) { - appApi.setUILanguage(availableLanguageCodes[availableLanguages[index]]) - } else { - FireBoltApi.get().localization.setlanguage(availableLanguages[index]).then(res => this.LOG("sucess language set ::::" + JSON.stringify(res))) - } + appApi.setUILanguage(availableLanguageCodes[availableLanguages[index]]) localStorage.setItem('Language',availableLanguages[index]) } @@ -181,12 +166,6 @@ export default class LanguageScreen extends Lightning.Component { const index = this._Languages.tag('List').index localStorage.setItem('LanguageSelectedIndex', index) this.updateUILanguage(index) - let path = location.pathname.split('index.html')[0] - let url = path.slice(-1) === '/' ? "static/loaderApp/index.html" : "/static/loaderApp/index.html" - let notification_url = location.origin + path + url - this.LOG("LanguageScreen notification_url: " + JSON.stringify(notification_url)) - appApi.launchResident(notification_url, loader).catch(err => { }) - RDKShellApis.setVisibility(GLOBALS.selfClientName, false) location.reload(); } } diff --git a/accelerator-home-ui/src/views/AppStore.js b/accelerator-home-ui/src/views/AppStore.js index 5c621bc..774392a 100644 --- a/accelerator-home-ui/src/views/AppStore.js +++ b/accelerator-home-ui/src/views/AppStore.js @@ -51,6 +51,7 @@ export default class AppStore extends Lightning.Component { } catch (error) { this.ERR("Failed to get App Catalog Info:" + JSON.stringify(error)) } + Catalog.sort((a, b) => (a.name || '').localeCompare(b.name || '')) this.tag('Catalog').add(Catalog.map((element) => { return { h: AppCatalogItem.height + 90, w: AppCatalogItem.width, info: element } })); From 692365c8525f7cc309810fa8b8dd9ce7567cd705 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 26 Mar 2026 17:15:33 +0530 Subject: [PATCH 15/52] Addressed the review comments --- accelerator-home-ui/src/App.js | 2 +- .../overlays/OtherSettings/LanguageScreenOverlay.js | 9 ++------- .../screens/OtherSettingsScreens/LanguageScreen.js | 11 +---------- .../src/screens/SplashScreens/LanguageScreen.js | 3 --- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index dce4069..9756e8f 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -2144,7 +2144,7 @@ export default class App extends Router.App { Router.navigate('menu'); } else if(notification.newState === PowerState.POWER_STATE_LIGHT_SLEEP && notification.currentState === PowerState.POWER_STATE_DEEP_SLEEP){ - appApi.setPowerState("ON").then(res => { + appApi.setPowerState(PowerState.POWER_STATE_ON).then(res => { this.LOG("Device woke up from DEEP_SLEEP to LIGHT_SLEEP . setPowerState result: " + JSON.stringify(res)) }).catch(err => { this.ERR("Failed to set power state to ON when device woke up from DEEP_SLEEP to LIGHT_SLEEP. Error: " + JSON.stringify(err)) diff --git a/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js b/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js index a4bee32..b44ebf0 100644 --- a/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js +++ b/accelerator-home-ui/src/overlays/OtherSettings/LanguageScreenOverlay.js @@ -20,15 +20,10 @@ import { Language, Lightning } from '@lightningjs/sdk' import LanguageItem from '../../items/LanguageItem' import { availableLanguages, availableLanguageCodes } from '../../Config/Config' import AppApi from '../../api/AppApi'; -import RDKShellApis from '../../api/RDKShellApis'; -import thunderJS from 'ThunderJS'; -import { CONFIG, GLOBALS } from '../../Config/Config' -import { Metrics } from '@firebolt-js/sdk'; -import FireBoltApi from '../../api/firebolt/FireBoltApi'; + + const appApi = new AppApi() -const thunder = thunderJS(CONFIG.thunderConfig) -const loader = 'Loader' export default class LanguageScreen extends Lightning.Component { constructor(...args) { diff --git a/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js b/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js index 8cfeeab..322ca3f 100644 --- a/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js +++ b/accelerator-home-ui/src/screens/OtherSettingsScreens/LanguageScreen.js @@ -20,16 +20,12 @@ import { Language, Lightning, Router } from '@lightningjs/sdk' import LanguageItem from '../../items/LanguageItem' import { availableLanguages, availableLanguageCodes, CONFIG } from '../../Config/Config' import AppApi from '../../api/AppApi'; -import RDKShellApis from '../../api/RDKShellApis'; import AlexaApi from '../../api/AlexaApi'; import thunderJS from 'ThunderJS'; -import { GLOBALS } from '../../Config/Config' -import FireBoltApi from '../../api/firebolt/FireBoltApi'; -import { Metrics } from '@firebolt-js/manage-sdk'; + const appApi = new AppApi() const thunder = thunderJS(CONFIG.thunderConfig) -const loader = 'Loader' export default class LanguageScreen extends Lightning.Component { @@ -77,11 +73,6 @@ export default class LanguageScreen extends Lightning.Component { } _active() { - if ("ResidentApp" !== GLOBALS.selfClientName) { - this.OnLanguageChangedfirebolt = FireBoltApi.get().localization.listen("languageChanged", value => { - this.LOG('language changed successfully' + JSON.stringify(value)) - }) - } this._Languages = this.tag('LanguageScreenContents.Languages') this._Languages.h = availableLanguages.length * 90 this._Languages.tag('List').h = availableLanguages.length * 90 diff --git a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js index b1c0726..ed43b85 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js @@ -22,11 +22,8 @@ import { CONFIG, GLOBALS } from '../../Config/Config' import LanguageItem from '../../items/LanguageItem' import { availableLanguages, availableLanguageCodes } from '../../Config/Config' import AppApi from '../../api/AppApi' -import RDKShellApis from '../../api/RDKShellApis' -import FireBoltApi from '../../api/firebolt/FireBoltApi' const appApi = new AppApi() -const loader = 'Loader' export default class LanguageScreen extends Lightning.Component { constructor(...args) { From ebd8a03c71d67f0e742253564cca579ef7da62f6 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 26 Mar 2026 17:26:37 +0530 Subject: [PATCH 16/52] Addressed the review comments --- accelerator-home-ui/src/App.js | 8 ++++---- .../src/screens/SplashScreens/LanguageScreen.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 9756e8f..6a10881 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -255,8 +255,8 @@ export default class App extends Router.App { _captureKey(key) { this.LOG("Got keycode : " + JSON.stringify(key.keyCode)) this.LOG("powerState ===>" + JSON.stringify(GLOBALS.powerState)) - if (GLOBALS.powerState !== "ON") { - appApi.setPowerState("ON").then(res => { + if (GLOBALS.powerState !== PowerState.POWER_STATE_ON) { + appApi.setPowerState(PowerState.POWER_STATE_ON).then(res => { res ? this.LOG("successfully set the power state to ON from " + JSON.stringify(GLOBALS.powerState)) : this.LOG("Failure while turning ON the device") GLOBALS.powerState = PowerState.POWER_STATE_ON; this.LOG("powerState after ===>" + JSON.stringify(GLOBALS.powerState)) @@ -2132,7 +2132,7 @@ export default class App extends Router.App { appApi.getPowerState().then(res => { GLOBALS.powerState = res ? res.currentState : notification.newState }).catch(e => GLOBALS.powerState = notification.newState) - if (notification.newState !== "ON" && notification.currentState === "ON") { + if (notification.newState !== PowerState.POWER_STATE_ON && notification.currentState === PowerState.POWER_STATE_ON) { this.LOG("onPowerModeChanged Notification: power state was changed from ON to " + JSON.stringify(notification.newState)) //TURNING OFF THE DEVICE @@ -2150,7 +2150,7 @@ export default class App extends Router.App { this.ERR("Failed to set power state to ON when device woke up from DEEP_SLEEP to LIGHT_SLEEP. Error: " + JSON.stringify(err)) }) } - else if (notification.newState === "ON" && notification.currentState !== "ON") { + else if (notification.newState === PowerState.POWER_STATE_ON && notification.currentState !== PowerState.POWER_STATE_ON) { //TURNING ON THE DEVICE Storage.remove(SLEEP_STATE) } diff --git a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js index ed43b85..f6cd056 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/LanguageScreen.js @@ -17,8 +17,8 @@ * limitations under the License. **/ -import { Lightning, Router, Language, Storage } from '@lightningjs/sdk' -import { CONFIG, GLOBALS } from '../../Config/Config' +import { Lightning, Router, Language } from '@lightningjs/sdk' +import { CONFIG } from '../../Config/Config' import LanguageItem from '../../items/LanguageItem' import { availableLanguages, availableLanguageCodes } from '../../Config/Config' import AppApi from '../../api/AppApi' From da695ef5bf5c1f2894faabba44aac9d8db055337 Mon Sep 17 00:00:00 2001 From: Adam Stolcenburg Date: Thu, 26 Mar 2026 20:14:30 +0100 Subject: [PATCH 17/52] RDKEAPPRT-661 Add support for new authorization in App Catalog --- accelerator-home-ui/src/api/AppCatalog.js | 449 ++++++++++++++++++ accelerator-home-ui/src/api/DACApi.js | 106 +---- .../src/screens/AppCatalogLoginComponent.js | 3 + 3 files changed, 457 insertions(+), 101 deletions(-) create mode 100644 accelerator-home-ui/src/api/AppCatalog.js diff --git a/accelerator-home-ui/src/api/AppCatalog.js b/accelerator-home-ui/src/api/AppCatalog.js new file mode 100644 index 0000000..0a65a5d --- /dev/null +++ b/accelerator-home-ui/src/api/AppCatalog.js @@ -0,0 +1,449 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2026 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +import PackageManager from './PackageManagerApi'; +import AppApi from './AppApi'; + +const APP_DEFAULT_ARCH = "arm"; +const APP_STORE_RFC_KEY = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; + +const debug = false; + +let appCatalogHandler = null; + +export const eventTarget = new EventTarget(); + +export class AuthNeeded extends Event { + static eventName = 'authNeeded'; + + constructor() { + super(AuthNeeded.eventName); + } +} + +export class RefreshNeeded extends Event { + static eventName = 'refreshNeeded'; + + constructor() { + super(RefreshNeeded.eventName); + } +} + +class AuthExpiredError extends Error { + constructor(url) { + super(`Authentication expired (${url})`); + this.name = 'AuthExpiredError'; + } +} + +class PromiseQueue { + constructor() { + this.next = Promise.resolve(); + } + + enqueue(fn) { + let unlock; + const next = new Promise(resolve => { unlock = resolve; }); + const result = this.next.then(fn); + result.then(unlock, unlock); + this.next = next; + return result; + } +} + +async function getConfigUrlFromRFC() { + try { + const appApi = new AppApi(); + console.log("Resolving config URL from RFC "); + const result = await appApi.getRFCConfig(APP_STORE_RFC_KEY); + const rfcUrl = result?.RFCConfig?.[APP_STORE_RFC_KEY]; + if (typeof rfcUrl === "string" && rfcUrl.trim().length > 0) { + const resolvedConfigUrl = rfcUrl.trim(); + console.log("Resolved config URL from RFC "); + return resolvedConfigUrl; + } + console.warn("Config RFC URL empty or invalid"); + return null; + } catch (err) { + console.error("Failed to get config URL from RFC", err); + return null; + } +} + +async function getConfigUrlFromPackageManager() { + try { + console.log("Resolving config URL from PackageManager..."); + const config = await PackageManager.get().configuration(); + console.log("Resolved server config URL from PackageManager: "); + if (typeof config?.configUrl !== "string" || config.configUrl.trim().length === 0) { + throw new Error("Invalid config: " + JSON.stringify(config)); + } + + return config.configUrl.trim(); + } catch (err) { + console.error("Failed to resolve config URL from PackageManager", err); + throw err; + } +} + +let serverURL = null; +let serverURLPromise = null; + +async function getServerURL() { + if (!serverURL) { + if (!serverURLPromise) { + async function resolve() { + let url = await getConfigUrlFromRFC(); + + if (!url) { + url = await getConfigUrlFromPackageManager(); + } + console.log(`Server URL: ${url}`); + return url; + } + + serverURLPromise = resolve(); + } + + try { + serverURL = await serverURLPromise; + } catch (err) { + serverURLPromise = null; + throw err; + } + } + + return serverURL; +} + +class StubAppCatalogHandler { + getApps(offset, limit) { + return { applications: [] }; + } + + getAppDetails(id, version) { + throw new Error('getAppDetails() is not supported'); + } + + makeDownloadURL(url) { + throw new Error('makeDownloadURL() is not supported'); + } +} + +class LegacyAppCatalogHandler { + constructor(configURL) { + this.configURL = configURL; + this.storeConfig = null; + } + + async getStoreConfig() { + if (!this.storeConfig) { + let resolvedConfigUrl = this.configURL; + + const fetchResponse = await fetch(resolvedConfigUrl); + if (!fetchResponse.ok) { + throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); + } + const responseObject = await fetchResponse.json(); + + if (typeof responseObject?.["appstore-catalog"]?.url !== "string") { + throw new Error("Invalid response object: " + JSON.stringify(responseObject)); + } + const catalog = responseObject["appstore-catalog"]; + this.storeConfig = { url: catalog.url }; + + if (typeof catalog?.authentication?.user === "string" && + typeof catalog?.authentication?.password === "string") { + this.storeConfig.authHeader = + "Basic " + btoa(catalog.authentication.user + ':' + catalog.authentication.password); + } + } + + return this.storeConfig; + } + + async fetchStoreObject(request) { + let config = await this.getStoreConfig(); + let headers = new Headers(); + + if (config.authHeader) { + headers.append("Authorization", config.authHeader); + } + + let requestOptions = { + method: 'GET', + headers, + redirect: 'follow', + }; + + const fetchResponse = await fetch(config.url + request, requestOptions); + if (!fetchResponse.ok) { + throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); + } + + return fetchResponse.json(); + } + + getAppDetails(id, version) { + return this.fetchStoreObject("/apps/" + id + ":" + version + "?arch=" + APP_DEFAULT_ARCH); + } + + async getApps(offset, limit) { + const request = "/apps?arch=" + APP_DEFAULT_ARCH + "&offset=" + offset + "&limit=" + limit; + + try { + return await this.fetchStoreObject(request); + } catch (err) { + console.error(`fetchStoreObject(${request}) ${err}`); + throw err; + } + } + + makeDownloadURL(url) { + return url; + } +} + +class AppCatalogHandler { + constructor(serverURL) { + this.serverURL = serverURL; + this.authURL = this.serverURL + '/auth'; + this.appCatalogURL = this.serverURL + '/appcatalog'; + this.timerId = null; + this.queue = new PromiseQueue(); + } + + async fetch(url, options) { + const response = await this.queue.enqueue(() => fetch(url, { credentials: 'include', ...options })); + if (response.status === 401 || response.status === 403) { + this.cancelRefresh(); + throw new AuthExpiredError(url); + } + if (!response.ok) { + throw new Error(`Unexpected response: ${response.status}: ${response.statusText} (${url})`); + } + return response; + } + + async postAuthObject(request, obj) { + let options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + body: JSON.stringify(obj), + }; + + const url = this.authURL + request; + const response = await this.fetch(url, options); + const responseObj = await response.json(); + if (debug) { + console.log(`Auth response: ${JSON.stringify(responseObj, null, 2)}`); + } + return responseObj; + } + + calculateTimeout(expiresIn) { + const MIN = 60; + const MAX = 4 * 60 * 60; // 4 hours + + let timeout = Math.min(Math.max(expiresIn / 2, MIN), MAX); + + if (debug) { + console.log(`Calculated timeout: ${timeout}`); + } + + return timeout * 1000; + } + + scheduleRefresh(response, onAuthExpired) { + if (typeof response.expiresIn !== "number") { + return; + } + const expiresIn = response.expiresIn; + + this.cancelRefresh(); + + this.timerId = setTimeout(async () => { + this.timerId = null; + try { + const refreshResponse = await this.refresh(); + this.scheduleRefresh(refreshResponse, onAuthExpired); + } catch (err) { + console.warn(`Refresh failed: ${err}`); + onAuthExpired(); + } + }, this.calculateTimeout(expiresIn)); + } + + cancelRefresh() { + if (this.timerId) { + clearTimeout(this.timerId); + this.timerId = null; + } + } + + async refresh() { + return this.postAuthObject('/refresh', {}); + } + + async login(user, pass) { + this.cancelRefresh(); + return this.postAuthObject('/login', { username: user, password: pass }); + } + + async fetchAppCatalogObject(request) { + const url = this.appCatalogURL + request; + const fetchResponse = await this.fetch(url, { method: 'GET', redirect: 'follow' }); + const result = await fetchResponse.json(); + if (debug) { + console.log(`${url} : ${JSON.stringify(result, null, 2)}`); + } + return result; + } + + async getAppDetails(id, version) { + return this.fetchAppCatalogObject("/apps/" + id + ":" + version + "?arch=" + APP_DEFAULT_ARCH); + } + + async getApps(offset, limit) { + const request = "/apps?arch=" + APP_DEFAULT_ARCH + "&offset=" + offset + "&limit=" + limit; + + try { + return await this.fetchAppCatalogObject(request); + } catch (err) { + console.error(`fetchAppCatalogObject(${request}) ${err}`); + throw err; + } + } + + async getServiceToken(token) { + const url = this.authURL + "/servicetokens/" + token; + const response = await this.fetch(url, { method: 'GET', redirect: 'follow' }); + const result = await response.json(); + if (debug) { + console.log(`${url}: ${JSON.stringify(result, null, 2)}`); + } + return result; + } + + async makeDownloadURL(url) { + const token = await this.getServiceToken('download-manager'); + const downloadURL = new URL(url); + downloadURL.searchParams.set('token', token.token); + return downloadURL.toString(); + } +} + +let initPromise = null; + +function handleAuthExpired(handler) { + if (appCatalogHandler === handler) { + appCatalogHandler = new StubAppCatalogHandler(); + eventTarget.dispatchEvent(new AuthNeeded()); + } +} + +async function callAndHandleAuthExpired(handler, fn) { + try { + return await fn(); + } catch (err) { + if (err instanceof AuthExpiredError) { + handleAuthExpired(handler); + } + throw err; + } +} + +async function initAppCatalogHandler() { + if (!initPromise) { + async function init() { + appCatalogHandler = new StubAppCatalogHandler(); + + try { + const url = await getServerURL(); + + if (url.endsWith('/cpe.json')) { + appCatalogHandler = new LegacyAppCatalogHandler(url); + return; + } + + const handler = new AppCatalogHandler(url); + const refreshResponse = await handler.refresh(); + handler.scheduleRefresh(refreshResponse, () => handleAuthExpired(handler)); + appCatalogHandler = handler; + } catch (err) { + console.log(`initAppCatalogHandler() ${err}`); + if (err instanceof AuthExpiredError) { + eventTarget.dispatchEvent(new AuthNeeded()); + } else { + throw err; + } + } + } + + initPromise = init().catch(() => { + initPromise = null; + }); + } + return initPromise; +} + +export async function isLoggedIn() { + await initAppCatalogHandler(); + return appCatalogHandler instanceof AppCatalogHandler; +} + +export async function login(user, pass) { + await initAppCatalogHandler(); + + const handler = appCatalogHandler instanceof AppCatalogHandler + ? appCatalogHandler + : new AppCatalogHandler(await getServerURL()); + + try { + const loginResponse = await handler.login(user, pass); + appCatalogHandler = handler; + handler.scheduleRefresh(loginResponse, () => handleAuthExpired(handler)); + eventTarget.dispatchEvent(new RefreshNeeded()); + return true; + } catch (err) { + console.warn(`Login failed: ${err}`); + return false; + } +} + +export async function getApps(offset, limit) { + await initAppCatalogHandler(); + const handler = appCatalogHandler; + return callAndHandleAuthExpired(handler, () => handler.getApps(offset, limit)); +} + +export async function getAppDetails(id, version) { + await initAppCatalogHandler(); + const handler = appCatalogHandler; + return callAndHandleAuthExpired(handler, () => handler.getAppDetails(id, version)); +} + +export async function makeDownloadURL(url) { + await initAppCatalogHandler(); + const handler = appCatalogHandler; + return callAndHandleAuthExpired(handler, () => handler.makeDownloadURL(url)); +} diff --git a/accelerator-home-ui/src/api/DACApi.js b/accelerator-home-ui/src/api/DACApi.js index 3ab198c..79766e0 100644 --- a/accelerator-home-ui/src/api/DACApi.js +++ b/accelerator-home-ui/src/api/DACApi.js @@ -20,11 +20,11 @@ import DownloadManager from './DownloadManagerApi'; import PackageManager from './PackageManagerApi'; import AppManager from './AppManagerApi'; -import AppApi from './AppApi'; import AppController from '../AppController'; import { ThunderError } from './ThunderError'; import { Metrics } from '@firebolt-js/sdk' import { SIDELOADED_APP_DEFAULT_ICON, deriveNameFromPackageId } from '../helpers/DACAppPresentation' +import { getApps, getAppDetails, makeDownloadURL } from './AppCatalog'; // the size that is assumed if it is not possible to retrieve package size // from the server, according to server API this should never happen @@ -37,10 +37,6 @@ const APPS_REQUESTS_MAX = 5; const APP_DETAILS_KEY = "refui.details"; -const APP_DEFAULT_ARCH = "arm"; - -const APP_STORE_RFC_KEY = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; - function makeLogMessage(call, err) { return err.toString() + " <=> " + call; } @@ -72,112 +68,23 @@ class OperationLock { }; let packageLock = new OperationLock(); -let storeConfig = null; - -async function getConfigUrlFromRFC() { - try { - const appApi = new AppApi(); - console.log("Resolving DAC Store URL from RFC "); - const result = await appApi.getRFCConfig(APP_STORE_RFC_KEY); - const rfcUrl = result?.RFCConfig?.[APP_STORE_RFC_KEY]; - if (typeof rfcUrl === "string" && rfcUrl.trim().length > 0) { - const resolvedConfigUrl = rfcUrl.trim(); - console.log("Resolved DAC Store URL from RFC "); - return resolvedConfigUrl; - } - console.warn("DAC Store RFC URL empty or invalid"); - return null; - } catch (err) { - console.error("Failed to get DAC Store URL from RFC", err); - return null; - } -} - -async function getConfigUrlFromPackageManager() { - try { - console.log("Resolving DAC Store URL from PackageManager..."); - const config = await PackageManager.get().configuration(); - console.log("Resolved DAC Store URL from PackageManager: "); - if (typeof config?.configUrl !== "string" || config.configUrl.trim().length === 0) { - throw new Error("Invalid config: " + JSON.stringify(config)); - } - - return config.configUrl.trim(); - } catch (err) { - console.error("Failed to resolve DAC Store URL from PackageManager", err); - throw err; - } -} - -async function getStoreConfig() { - if (!storeConfig) { - console.log("Resolving DAC Store config URL..."); - let resolvedConfigUrl = await getConfigUrlFromRFC(); - - if (!resolvedConfigUrl) { - resolvedConfigUrl = await getConfigUrlFromPackageManager(); - } - - console.log("Resolved DAC Store config URL "); - const fetchResponse = await fetch(resolvedConfigUrl); - if (!fetchResponse.ok) { - throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); - } - const responseObject = await fetchResponse.json(); - if (typeof responseObject?.["appstore-catalog"]?.url !== "string") { - throw new Error("Invalid response object: " + JSON.stringify(responseObject)); - } - storeConfig = responseObject["appstore-catalog"]; - } - - return storeConfig; -} - -async function fetchStoreObject(request) { - let config = await getStoreConfig(); - let headers = new Headers(); - - if (typeof config?.authentication?.user === "string" && - typeof config?.authentication?.password === "string") { - headers.append( - "Authorization", - "Basic " + btoa(config.authentication.user + ':' + config.authentication.password) - ); - } - - let requestOptions = { - method: 'GET', - headers, - redirect: 'follow', - }; - - const fetchResponse = await fetch(config.url + request, requestOptions); - if (!fetchResponse.ok) { - throw new Error(`Unexpected response: ${fetchResponse.status}: ${fetchResponse.statusText}`); - } - - return fetchResponse.json(); -} export async function getAppCatalogInfo() { let result = []; let offset = 0; for (let i = 0; i < APPS_REQUESTS_MAX; ++i) { - const request = "/apps?arch=" + APP_DEFAULT_ARCH + "&offset=" + offset + "&limit=" + APPS_REQUEST_LIMIT; - console.log(`Requesting: ${request}`); try { - const appsResponse = await fetchStoreObject(request); + const appsResponse = await getApps(offset, APPS_REQUEST_LIMIT); if (!Array.isArray(appsResponse?.applications)) { break; } result = result.concat(appsResponse.applications); - if (result.length >= appsResponse?.meta?.resultSet?.total ?? 0) { + if (result.length >= (appsResponse?.meta?.resultSet?.total ?? 0)) { break; } offset = result.length; } catch (err) { - console.error(`fetch(${request}) ${err}`); Metrics.error(Metrics.ErrorType.OTHER, "DACApiError", err.toString(), false, null); break; } @@ -186,10 +93,6 @@ export async function getAppCatalogInfo() { return result; } -function getAppDetails(id, version) { - return fetchStoreObject("/apps/" + id + ":" + version + "?arch=" + APP_DEFAULT_ARCH); -} - function retrieveURLAndSize(details) { if (typeof details?.header?.url === "string") { const url = details.header.url; @@ -223,7 +126,8 @@ async function downloadAndInstall(pkg, downloadedSize, totalSize, progress) { const downloadId = await new Promise(async (resolve, reject) => { try { - await DownloadManager.get().download(pkg.url, (downloadId, percent, failReason) => { + const downloadURL = await makeDownloadURL(pkg.url); + await DownloadManager.get().download(downloadURL, (downloadId, percent, failReason) => { if (!failReason) { if (percent !== 100) { progress((downloadedSize + pkg.size * percent / 100) / totalSize, "Downloading"); diff --git a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index 509f3dc..fb8697f 100644 --- a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -21,6 +21,7 @@ import { CONFIG } from '../Config/Config'; import { Keyboard } from '../ui-components/index' import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' import PasswordSwitch from './PasswordSwitch'; +import { login } from '../api/AppCatalog'; export default class AppCatalogLoginComponent extends Lightning.Component { @@ -52,6 +53,8 @@ export default class AppCatalogLoginComponent extends Lightning.Component { } else { this.LOG('App Catalog Login - credentials submitted') + login(this.textCollection['EnterUsername'], this.textCollection['EnterPassword']) + .then(result => console.log(result ? 'Login successful' : 'Login failed')) } } From e7726279d8fcc66ab9d76072394ba7df2afe9733 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Fri, 27 Mar 2026 16:22:33 +0530 Subject: [PATCH 18/52] RDKEAPPRT-646 Reload app catalog data after login --- accelerator-home-ui/src/api/AppCatalog.js | 2 +- .../src/screens/AppCatalogLoginComponent.js | 12 +++++++++- accelerator-home-ui/src/views/AppStore.js | 23 ++++++++++++++++++- accelerator-home-ui/src/views/MainView.js | 11 +++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/accelerator-home-ui/src/api/AppCatalog.js b/accelerator-home-ui/src/api/AppCatalog.js index 0a65a5d..9256ae6 100644 --- a/accelerator-home-ui/src/api/AppCatalog.js +++ b/accelerator-home-ui/src/api/AppCatalog.js @@ -23,7 +23,7 @@ import AppApi from './AppApi'; const APP_DEFAULT_ARCH = "arm"; const APP_STORE_RFC_KEY = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; -const debug = false; +const debug = true; let appCatalogHandler = null; diff --git a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index fb8697f..a6e1fa0 100644 --- a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -54,7 +54,17 @@ export default class AppCatalogLoginComponent extends Lightning.Component { else { this.LOG('App Catalog Login - credentials submitted') login(this.textCollection['EnterUsername'], this.textCollection['EnterPassword']) - .then(result => console.log(result ? 'Login successful' : 'Login failed')) + .then(result => { + if (result) { + this.LOG('Login successful - navigating back') + if (!Router.isNavigating()) { + Router.back() + } + } else { + this.ERR('Login failed') + } + }) + .catch(err => this.ERR('Login error: ' + err)) } } diff --git a/accelerator-home-ui/src/views/AppStore.js b/accelerator-home-ui/src/views/AppStore.js index 774392a..47608ec 100644 --- a/accelerator-home-ui/src/views/AppStore.js +++ b/accelerator-home-ui/src/views/AppStore.js @@ -3,6 +3,7 @@ import { Grid } from "@lightningjs/ui"; import { CONFIG } from "../Config/Config"; import AppCatalogItem from "../items/AppCatalogItem"; import { getAppCatalogInfo } from "../api/DACApi" +import { eventTarget, RefreshNeeded } from '../api/AppCatalog' export default class AppStore extends Lightning.Component { @@ -44,20 +45,39 @@ export default class AppStore extends Lightning.Component { } } - async _firstEnable() { + _firstEnable() { + this._onRefreshNeeded = () => { + this.LOG('RefreshNeeded event received - reloading catalog') + this._loadCatalog() + } + eventTarget.addEventListener(RefreshNeeded.eventName, this._onRefreshNeeded) + } + + async _loadCatalog() { let Catalog = [] try { Catalog = await getAppCatalogInfo() } catch (error) { this.ERR("Failed to get App Catalog Info:" + JSON.stringify(error)) } + if (!Array.isArray(Catalog) || Catalog.length === 0) { + this.LOG('No apps available in catalog') + return + } Catalog.sort((a, b) => (a.name || '').localeCompare(b.name || '')) + this.tag('Catalog').clear() this.tag('Catalog').add(Catalog.map((element) => { return { h: AppCatalogItem.height + 90, w: AppCatalogItem.width, info: element } })); this._setState('Catalog') } + _detach() { + if (this._onRefreshNeeded) { + eventTarget.removeEventListener(RefreshNeeded.eventName, this._onRefreshNeeded) + } + } + _handleLeft() { @@ -76,6 +96,7 @@ export default class AppStore extends Lightning.Component { } _focus() { + this._loadCatalog() this._setState('Catalog') } diff --git a/accelerator-home-ui/src/views/MainView.js b/accelerator-home-ui/src/views/MainView.js index b70b891..7f4393f 100644 --- a/accelerator-home-ui/src/views/MainView.js +++ b/accelerator-home-ui/src/views/MainView.js @@ -32,6 +32,7 @@ import NetworkManager from '../api/NetworkManagerAPI.js' import { getAppCatalogInfo, getInstalledDACApps, startDACApp } from '../api/DACApi.js' import { filterExcludedApps } from '../helpers/DACAppPresentation.js' import AppController from '../AppController.js' +import { eventTarget, RefreshNeeded } from '../api/AppCatalog.js' /** Class for main view component in home UI */ export default class MainView extends Lightning.Component { @@ -458,6 +459,13 @@ export default class MainView extends Lightning.Component { } AppController.get().addPackageChangedListener(this._onPackageChanged) + // Refresh DAC apps row when app catalog authentication changes + this._onCatalogRefreshNeeded = () => { + this.LOG('RefreshNeeded event received - refreshing DAC apps row') + this.refreshSecondRow() + } + eventTarget.addEventListener(RefreshNeeded.eventName, this._onCatalogRefreshNeeded) + this.dacApps = dacCatalog this.fireAncestors("$mountEventConstructor", registerListener.bind(this)) @@ -469,6 +477,9 @@ export default class MainView extends Lightning.Component { _detach() { // Unsubscribe to avoid stale references to this MainView instance AppController.get().removePackageChangedListener(this._onPackageChanged) + if (this._onCatalogRefreshNeeded) { + eventTarget.removeEventListener(RefreshNeeded.eventName, this._onCatalogRefreshNeeded) + } } _firstActive() { From 90f4f8cce30ccb2a2b9d65b9aaedaf74741e2d25 Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Mon, 30 Mar 2026 16:43:51 -0400 Subject: [PATCH 19/52] RDKEAPPRT-646 Reload app catalog data after login - Disable debug logging --- accelerator-home-ui/src/api/AppCatalog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accelerator-home-ui/src/api/AppCatalog.js b/accelerator-home-ui/src/api/AppCatalog.js index 9256ae6..0a65a5d 100644 --- a/accelerator-home-ui/src/api/AppCatalog.js +++ b/accelerator-home-ui/src/api/AppCatalog.js @@ -23,7 +23,7 @@ import AppApi from './AppApi'; const APP_DEFAULT_ARCH = "arm"; const APP_STORE_RFC_KEY = "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.DAC.ConfigURL"; -const debug = true; +const debug = false; let appCatalogHandler = null; From 629ff83e2338e233c40492d4153107cdd4b41156 Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Tue, 31 Mar 2026 16:05:51 -0400 Subject: [PATCH 20/52] RDKEAPPRT-677 Changelog and package config/version updates for 6.0.0 Signed-off-by: yashaswini-rk --- CHANGELOG.md | 21 +++++++++++++++++++ accelerator-home-ui/settings.json | 2 +- .../package-configs/com.rdkcentral.refui.json | 8 +++---- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de3f7df..3158b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,33 @@ 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). +#### [6.0.0](https://github.com/rdkcentral/rdke-refui/compare/5.0.24...6.0.0) + +- To refresh the App store and main view when the authentication done [`#166`](https://github.com/rdkcentral/rdke-refui/pull/166) +- RDKEAPPRT-661 Add support for new authorization in App Catalog [`#165`](https://github.com/rdkcentral/rdke-refui/pull/165) +- RDKEAPPRT-621,606,648,644 fix for Language screen and powerstate issue [`#164`](https://github.com/rdkcentral/rdke-refui/pull/164) +- RDKEAPPRT-646 Create the Username, Password page and add it inside the settings route [`#163`](https://github.com/rdkcentral/rdke-refui/pull/163) +- RDKEAPPRT-645 Add default error overlay when user tries to enter VOD content [`#162`](https://github.com/rdkcentral/rdke-refui/pull/162) +- RDKEAPPRT-612 :Add dac store details via RFC [`#160`](https://github.com/rdkcentral/rdke-refui/pull/160) +- RDKEAPPRT-626,627,628,605,608,622 Fix error and uninstall overlay screen with bug fixes [`#161`](https://github.com/rdkcentral/rdke-refui/pull/161) +- RDKEAPPRT-601,602 App side loading and App side loading and closeApp() function [`#158`](https://github.com/rdkcentral/rdke-refui/pull/158) +- To merge the changes from Feature/app managers to develop [`#157`](https://github.com/rdkcentral/rdke-refui/pull/157) +- RDKEAPPRT-576 Improve focus management [`#155`](https://github.com/rdkcentral/rdke-refui/pull/155) +- RDKEAPPRT-341 App managers intake: abstractions, API migration and YouTube Launch Support [`#146`](https://github.com/rdkcentral/rdke-refui/pull/146) +- RDKEAPPRT-571 Create UI prototype with My Apps, Recommended Apps, VOD Rows and Appinfo (#156) [`eff1a86`](https://github.com/rdkcentral/rdke-refui/commit/eff1a864e55c28ed1c542e26f818d20f082a6dca) +- RDKEAPPRT-538 Add basic integration with the RDK Reference DAC 2.0 App Store (#152) [`82eda3d`](https://github.com/rdkcentral/rdke-refui/commit/82eda3d7b34b80be63bdf3d0cb39d6c3f7f1f681) +- Changes for the error and uninstall overlay screen then some bug fixes also part of this [`749f89d`](https://github.com/rdkcentral/rdke-refui/commit/749f89d0af61e7aab7d96cb70a392e4efb8f8020) + #### [5.0.24](https://github.com/rdkcentral/rdke-refui/compare/5.0.20...5.0.24) +> 12 February 2026 + +- RDKEAPPRT-575 [RDKUI] 5.0.24 Merge latest changes from develop to main, create release tag, and publish release. [`#154`](https://github.com/rdkcentral/rdke-refui/pull/154) - RDKEAPPRT-268 [RDK UI] Replace deprecated APIs for USB Media Device [`#153`](https://github.com/rdkcentral/rdke-refui/pull/153) - RDKEAPPRT-394 Adopt to New APIs for deprecated ones if not yet [`#151`](https://github.com/rdkcentral/rdke-refui/pull/151) - RDKEAPPRT-533-[RDK UI] Device is not discovered via DIAL after re-enabling Local Device Discovery option [`#150`](https://github.com/rdkcentral/rdke-refui/pull/150) - RDKEAPPRT-518 All SSIDs are not visible in FTI SSID selection screen [`#149`](https://github.com/rdkcentral/rdke-refui/pull/149) +- RDKEAPPRT-575 Changelog updates for 5.0.24 [`59d8252`](https://github.com/rdkcentral/rdke-refui/commit/59d8252ac9401f7882716fc5c055346653004996) - Merge tag '5.0.20' into develop [`4413c1c`](https://github.com/rdkcentral/rdke-refui/commit/4413c1cf7d14b54c8952299b291a44f311d7033e) #### [5.0.20](https://github.com/rdkcentral/rdke-refui/compare/5.0.17...5.0.20) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index b73ffb3..2c24f86 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "5.0.24" + "version": "6.0.0" } } diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 6e1a209..1ae1208 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,12 +1,12 @@ { "id": "com.rdkcentral.refui", - "version": "0.0.1", - "versionName": "develop", + "version": "6.0.0", + "versionName": "6.0.0", "name": "RDK Ref UI Home Screen", "packageType": "application", - "entryPoint": "file:///usr/share/refui/index.html", + "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", "dependencies": { - "com.rdkcentral.wpe-develop": "0.0.1" + "com.rdkcentral.wpe": "0.2.0" }, "permissions": [ "urn:rdk:permission:home-app", From c2b261ff1ea9e4e72a8750f77652d6f4261775ce Mon Sep 17 00:00:00 2001 From: yashaswini Date: Tue, 31 Mar 2026 21:29:39 +0000 Subject: [PATCH 21/52] RDKEAPPRT-680:Update the new logo files --- accelerator-home-ui/static/images/RDKLogo.png | Bin 16213 -> 10347 bytes .../static/images/splash/RDKLogo.png | Bin 14231 -> 10347 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/accelerator-home-ui/static/images/RDKLogo.png b/accelerator-home-ui/static/images/RDKLogo.png index 566bb3ee71f576811d964ae5fe382abddca2d22c..045d6147da790f393134e3d4e6f767d39070c230 100644 GIT binary patch literal 10347 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

D@giENVuig7^WtvF)kAS!CL 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 diff --git a/accelerator-home-ui/static/images/splash/RDKLogo.png b/accelerator-home-ui/static/images/splash/RDKLogo.png index 63669f85ef69ac61b06c0617fa09a0463cf0f09a..045d6147da790f393134e3d4e6f767d39070c230 100644 GIT binary patch literal 10347 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

D@giENVuig7^WtvF)kAS!CL zesGST=s0o+bQ*!8A@%SgcR_Uq+2%@r7G@cSSo4#ZSvj)Pb~^z{h5)CFRO#g9Dfsvf z3UlV5Xk2}g8R^Vv4+7>D;Bf71Hss8Lzq8-;7P}0kRjsb{caFc^$hsRk zfI#=SrSOnV5dT^hy#Hg%+qai!&i5-0Mpz!fi|-G%r^iVS7y;AEe}m7@4-o2m4Nl6d zz#cC+atJsC;);MMCg;9Mkrx1BcYfCMIIJh< zp-1MqZGDFqE+iTOv*FVU&f)(AXr6=~;d@ay;scnu;6z*I^xH+Cpr9Fbb?*b-Re-Ly zs!Ua&G76#er*X(Kv+cKhq0c$~FOYD@L?O^M^$L4!gEyCRxb1ot@Mdd?Y$@E@55D{q zF`2{>fRHs^PH<-t*vkBQ3-Hchg?s`&3q6dYQOjWd*{!pZ-TkS9KuZH}(a{R`uVeTL%U5tNizUdc@h9HkBdB8rK5pF;dAAov$JZfDu}Uhw1@%w9FZIeyDX zJMo=DpljT03iv;t{urKjIuo>xY>yOSC<+ixy9IMA2HI29O(hE&09giLHgV=0txiF+ z48wqov4}LBjY$48Zd#kn`4Fs~fuFPe{HkKQcWDwY`UQ@G#|Xe$Dy zaX2ye4fxGJ<1L%W_DCTRJ>>rZ00960PNmy<00006Nkl003eL1^@s6rk){S00001b5ch_0Itp) z=>PyA07*naRCr$PT?u#;MfU&oF*D%^2_QEDE&@sx%jE+D&#A|Qew z;Kd++k^5E=)a4SC2r4&+Aj|xz#!P(T|=v_%mh^?{b_2AOzr?+8^YAA?YCeC7j8+jH9a^h+E792|z-E0=u1q-L3>dJn6U`9_aZ$5E2iCeo_!-5w=6p zb-~F1mjjN!4i4GixU1lB1t1qekO~DUIDPmumVAB@vXTNTcM)mHX?W@>8A%N}B*ZDO zj|>+7-RqJAID!?&4}qYT|Lfhg)CB>!aP||do-$OGb3-}~may1)#3gZvtlJ&W_8tq6 zNXmRuXG6Cb(c*;Y{25CZ^ubJfDu)%vF9TdT|29-pr_DO|l>!zU!Jf?%@OJ!gO{6$| zh)V&zRQ)k%+-4A*4s(Um*KZ7m_8P_Vp&;SZ^AAxt@Vpbem43u?bBPNCfnE$r|`pT2X zKuB#UGVk^G7ub;FV6n=$aC#b6P9750fKK(=USYPI;8SnJKULw8hOb} zG!0z?^g6}>Isl7RLdvNbST%KU_yRiB%+E!lL-)a`UTX+sNdzH+slv%|GB}>Y@xMl3 z|HkQ$QOi3U9_vZpvufWR7|U^fHwFlMF;;9Z&>)#<5ejgVAaO4)?n8yDcz zfgOmsGs9$HXMi3&A#%$AQMG$Pl)-bCkdgWa{@ngK_HEjMW)0F!=D#NmodLRACa7kf zc(nq$cAJ876`qHpSO8*x^`a1=<9Qi^n1bZPqp^L#SC~`B0o**;F%3O<3)ZZWnTBo_ zWrN$V0%~fb8a!|f8ENbA`}!G(&fZ|6wx$94nqG4tE8R4cJ9~me0nH*KSO^HYj@)Y- zv3bQ9>|V7Ev9Z)*W1_ZhqK1Cq)O4(z8h$2s3g#y-Rz~X=$DvB~e?yT~`--WuK{a!$ z?E;cd_rcF=*C4@8{c~=)0%L$~DhGnnIRo^dkUgM-D&Tp57pPhO3oMyE33Y6TP0-eu zh8|G1dOetSxDzc3&K#M8MYG1BqH@wav-K^2PVdl-IoO4#$(=)79FH{IjXodDL7B)0 zAWKv$HxtaMqcefz`~zeAzKm___Pb3d`6Y${y4PzcY#K5^4;xnbJyB|kl^{8iuyoO2 zB(MJs8#Yi?!6?Ty2IzjX$kYxLh!zQi9LCQJdn5YpMA+kR)7t!>fr%P=c-^6M=-pdH zmHQjxp{Hg-Q5vat=B9!|>1gF6Fs|D`?DdSG|xp~ew&=cC=R zT1#ET%=h2G_g{Wj(CJ;rH1c@4Gp9Hm^b5o*n)W7GQn2>B!I<*qH-3exdYrKv&`%r# zK}o$s*EI76?Vd!dc2m^wJ)iNoDz``lRuyEP}gFu~W=%K;gqG!QDfnZ6+nk8={=im~|nng8rgPxMEp%V@R z6CzOd^0R2!{xc{_SrC(*->8+%7I6i8cTK|P&68m}aSaIx>P3BF5A$*_ibCP{duDPE zKb{#gW9k8GjYz}t&pM!Wqy31FFLDDYa(`f9YsT;<5WR5JJS(2Z&)+M||G4k8w?I(%q)MpC zo#x@ljVz6(505~r_OBy1*Jd)96YzopaHp_k)tj(gTmkzCnwZLKpBSd0o4dS%(K`e5 zU{F1D#w4&0)K{95f%i z*anhB!}QEFv(so5g0ypMv25-D@af0(9>f@+2V{i>bPzKDeGnYEX2)6vlt{&VFfFrK z*459jdg9xdGbdMPC>sOxa1|74y3M)15c7t;j;2ks{WHCn7(myG5uKEq;pwiEV2yZ4 z&7f*#7FBxq;&=%c&wPz})80XB%te2A#Q;5A7i_`vHUrREF86Sg6HZMLc^a!1wZ`L8hlE$g0!keuibNT_uMihnM54a|Sp))<4Q&jv3xcGWjA zGhvLDMcxM`V zIP%>+XVD_#!l|i9{$&UQ^gD}u<1xJJJARi>wbdVEQnfX&Jva3bAw=IX z^R$2aC)2#|SFU`I&nLf#*g9T^zTBpvvubN0Do#aAizXbB90!mv?GY^eEJNqD3w_O8 z4Ly0?TPCC}_LgTnI`+4q({ukuox4Xsa#n|;7?ax8^9-~^P=p-E{PFJr>E9tC;byfx zZ)aUVI}WRouRst=``HhBJya+_MZ;nRcCMd{oC8CB4STrdGt4TV%JI|_n+kTQP|fIh zxDG3{3Mv51J!_8l5O5=)c_JP|#7& z-7YV;JpHU7ZWh)yuP7FF)b!M@@Hylya~o(s6arhROw1h<2WQH9{mya4HJ3Z#5ZAX1 z{?YNjsC(a7^Gly{1U&sC9K@QhUd1%~7NfKJarkiF2LPe*b?hk)6d+V!h=`2yzhUCA zHTqBG0L%b%Eos78?B6~axsIITK=Pa4AOl1Yz!3{LVuQk!0hF?+UOO6AaEjh!2*si zqh=SAoaI0it9p=?=~by(vf9j3t>zq=ojnSl_8qN1&wp`@L#JRqs5~BjW(2C#>J3G) znq2x+D}kJIeG`6O&=-&1cNFpQst_0{z*J)}Q=p8TE9=V_3aA>7_X!C+c5Mcr)4L0HrV{rRW)R%xII>phm>mpXR|?8A^|Q6 z545R{mhBsZ=UYOwv;fCj;dIdb*SwG@HH6LbBR=cbQ@^*ni6-}8luxB$X>;b3!_e8| zP^(@K$dbiW9#GJ>*kt5fUyRjX4#(x=XZ2f43STI$6JqgOPsMG2@cn!I1amr|DS%El z7~4KfeWe{*w7BG-vySgn3Gf^A!0a+7Q*5+zNNUI-<}ae&8Pdv4Ld}+V^52ud@r@y? z@vg=mu&IW|^9k7T)r&grDa`?NE%ViB%%9R6F%^sdp)M(jLre_iIjvjHt9&-+!4{WtHt-wkqY9YSg3{^526gaww<)kj zJOM>9R$CJU3g~;$v3B#2(a=>uC#NxgYI7hZ-7IazOy>E~H;ros;uCn3U&q5%vmu)O za}+AqXa~tjvymD6&?_!J2kX9ViAh8E>$BPw3qaROpO$TK7ykL&0)W3Cl9OuY=3yYm zE8w}S*t2y6&Tjbgf)n@5?=H zF6Nz1yxYoHt5BwZ8Gz2KX({(%YVVR@a`&FQl-BKEe+@P3PJq)v@6?T2n>3n0#=386 zqP){rldDPf(DRtwOE#cu@NG}O~w!LE((BKOev5(wxV?29e9 zdiH6=J~b8Ksv3G=zI}yj1y(XH{eivP-a_WS-!W^J6bLY98oKw}ZOLqD8lW=`{WgK3 zoBDxEccI5yn<2}U4fMFxG_;?-iNV=F4*O`{W*T~6R=#$(Tk-y9(5c64I2}<2I%#Pk zqI+z3O#Em)9r2kz2{+$N~!H1RN6a?h7yCnU2SF_^tRQaoplK z2!F*GrVaQt8TPWF6j1DTKRw8A0=jXT;#3Wt0s3v6rum{rj^q&Y%u1ArZs#fpVT3@? z%z?n_g{={NZ3pajsx5f?FhKW~QvSE&(7t_X{Cnhgs92>vWCMLED98xHa*XZKSzqW{ z7@FMa0r}iH0c9J!kM{8c;K(g&;33Hqw-xXLaQWhVEc3L7n(w-bJ z29@s|Xe> zKXL^Er)7$BN3Rujdsk3Kr@Yyo+->ql!{yJYR8WSff-)}^l%**z9Xv(g6_o|bQ-&&U ze@4glCRpW5S{YR+tWB6zKyf+SpWN_NgK1CA2z~nr>jw4T%sG$8@GPTunk5P ze%n4wD-mI9zN}CU&^z>f6;*4^fTEtzjJQYF0DaYh=MjB<83S}*SQ6m26wo98em@#C z+X_Xt8mLhch~i#MeB*Icu%-EU?P7lF*Hu#o>n#_08;8`=rp^3R^)Kmh_9udGkZn6N2(-#a7hYUUvS z0KG|T>wV7~OHhIse0X(&^!jmasMHBWX$K7qB12B4C>CeY4r1!@J#S_bIB z+rdp4nE|>fWDP*4bVIMz_AykcxeT&QlZ+Upp#!VtcMmNRV}}KOKbZhR`Wjf$ zngaS6eEddd#5UTaAJ9)613?`qYMNUAAB$Cjf2m(NbnI`%V{JMi=E0AlNVQEbeQL4f z;Nq#}*!jyqTu8cL*xkSX)Kq&=0i6)AJ9L8x8Uo#fHlVXiafO>)tG9d%H5xEL4}pag zgeh={jTJEHi;>{@VQSf3W2`g^B1)gf$Nf8_PnSOsAMay@yHLDCCmdcHX+y(?JrMKY zSP(f93NcSJ=b(TWIUG$IkBP&^;6I%+gMDA_Nj{l|9)wkE@{pko=*%guXh5&tU>TI+ zZgOXL=pF~XCO`-S&GSn zasrjc)r%eDwk8bF^-wLe-!TKwjSE{-P3|n0yGIdH0lm#*s8NTR+(UbfnKe7jTf6DY z!yrfu(DPH7=EbbSVM37 z1gh3p3MisM8s9(5LYhu`Ol(4&PrW?zNXh4$VxZJM#cA1haz@|9ykph;d+Oz$$uaFQ+T5L1ORni zp?pTHi`&VsMc`aRTI#3xao$+qOlBy>n0o_24A8xyQh2oq13+gQdVzrcJ}lWzadsZD8+b(jtsVM|`T~xeY6iyT zd)CY?)~ons$ygjZFcr{UvQPuhZ^xRH@kuPPM3n z5f6dI2CQAw9B1q7^)Zh(Gr1eV0q^@@CU;6Jcj?nM@qKW|y>{eYH?lr_er{+v*##j5 zzpQ*46Zx4x+N91LdKfvy(RFY#qZ}UX zIsjFwy$PqYoQb7RDUeG5&f?b}d%|&S2c}PRglderH=DtYYHO@Gi#Oy7i#9Gm&zSJo z;C-w(OIWZB01e5pRBeVHLs!9(Q{J%BnN<4#mxbS!RKxhe*Hmr9`-f@h-qXs6mL*$5 zr<(EJ)bi-m)s9LvU)2tf#F#X*w{wT6&Tk6YhF_Pwfz#Xn42Q6^qJ+$?p-0_PW-f0n za8I?n3#-eWx2AewTZbpNhP-vuJ=G(>aZyl6?RIasD^K;w^VWLLOS$}Y;`7&gFRUKA zryB6IZ%;MQJ&j3!R#-jv+iRv1Sb0Lrr!qhkha%A{Cu7!t zComU82hN@N0h8Z;6EQ&U6AvMddQK%WX>9ZfBNo(UW#j#xOn&wN*i}bPE35HDRjy9dfLQ$$1 z3g*-fM6+FS7=cyxN+K3#X@GWx@jd=dHO=ZIwF%O=+APc) z+Y^gs{HP-bwTT)!i$nJyLnZ4DT@V#W&P~X^QV~%V?=dh;&l710h;jmF4v)fyISY}H zK%L==-QHu?9YvA*9cvH<6fgzQ=_%Q|5ASwrhs4B7IzT3r33scc!lkeu|J%y9luV2e18aRWP{Lfj!8_k<<_I`eWb@qn&M zJx`$ir5n~(0tHdP3_z!42YDeIxmkOl5FhI@ zhd8TLdk9V0%29_N8%mWc4UUuoQOZIPEf6g{Ktwp5qIyqAs1Zed%vpzmK#-Zf6!Yi2 zh!z!{I?RhKY%Q=NXOe~YC%HGM1Lpt%0Nc?Dur7P!LXg1}-`uxCqe>=Nec(9T^44Lb)@ zQok|{J#ZR&$O1Y6HM?tvTXQvZRhl^kR$Cfo+WX)XzZ_3hmvtO+gR>WVIVuBmF9}s5 zo0$dZC6br{{%Fks=or4A8H-t?Q*>T!Fq3;=*=CZ4Zj@8p$zvd-jw`Ivf67oWC*)^< zR0X)d8yc=z@az=WY+1-SKL)Emos2nk9L34}&Ya@>7t4_Bf#dvih@)S16VM02VQTH+ zkfdQ4Pl`Ykok+Vl24lv5gufE#CA}U8Ne$3V(a@PwT;MeH5CwFLO~R$~Gq8HzSBM+% z8LZX^AvukzGFb5PrJA}RW+UzVEUf-&3>H;SFD{_Yy=1Qwk)5d)f?!WEqQLR&DpKOC zMAh3$_ro-F-J}cZi*&={#bnH%{215v-znhCm>KfsJ)N^0q$NBH#{;Fwytdqb>Ng<CE z+-SS}N!+}pyf@wtg(YkAcATQ9n|BOv=2TRFf%tv?c@{<|p6A3Pf22>J^4j*%E@tV` z&hl#L#>Jrrf>Q;9`JSbI4ImRu z0`yQdxmzVrKwmX=uzK*M$(Fua5`{sdhogR@0gxnWemC1$juvPkxSaYcCJlZAb*miq z^AH?Bak+gcZpQB&(+T0C$;}X&piYPl?l%R9H9}Arp!-e7aO;48;{icP!lLPIk&}E0 z2?_p&1u_jiuu@R60i9~h6o&>)jzEn%ui>7i9|B4#D2h>~gbU`Tpw>J%itX!O#&4&$ zV}qTpov_o?sfM0T2#IDH;{v;KO&pB@x{1UM(XO?c&XO|`E9UpZot8fgx({T49$1E( z1n41rhn`nM&l}bmH!uRN+Pr`UO-6ypRRaR*JTHM4&SU3>0ocE14H72hgj*?97odY_ z=z(3hW{$=H-Aw9+UfMOFh_hSp zVADs?sOcg|j*0;Rb&iw4374^Z(|eGQ&Bllk+F?0N9tP-P!YCi6Nvt+OIk1D>q5D9y zaBNCV>pw<%_A^>quc0??{T7_L<}ajxlPW9+)HDWK z7BwgPH1_>I0*M=!p=m8MHXWAwHLxOL5}=2$$=w~cMxEk3-&t$U+HIe1g#Hshg&?$a z<$X8XiJQP`yNbPAW@GcOA0Xm#uEB?8QzVON=%$c0sGS-Q=th=L4Jv8Ec5rI)qo#FE zO<&1zhmm$_4o3E$gMW9rq@&Kcw}fCCy0?@vrd`PcbkBF_w^P$@=W#r<8vfPm6O@kp zm!_$ko-UTAPj*5f-y>nhn-i2wOn64A2XsHwE>BX;txb zuXjy) zgU$lOCtwDk8<+Z3EzBaG1(6Ryu*AAd`DVwO8ct+`I@C08?V;K?2hmECT|g_TN>ag# zf8g}t4fyeYTTwc9H)3LP)z;<$x%=}Npc}+!FS{`b&<%Bps|`gqCX9?`it|=OcN382 z#wb(9f*0+hA&b4?$e{^n%-uieo~8ZSk2zD~5mWw1fYzUvVso<@19YEB7VgF`5ITLbQQu?#~uZOkfWB8 z6@<%BSqU*QBnTe24A6~{1aEuM0KG}ip%A$b zAxjiEjaU;3B1)gfxPH&0_X|4_AMay+0%}F$2v!tfFu&0*u`-G&+kQc)>TLj9z|g5wCse}F@F)4CP04@jE%!YKxf5SJcuEO zxHul&KOP1_v@<|29J^p&Y{9kjUD4+0u~3vs0RVNVktIYqi5Nk)ur#Qb!7;+sL59mgEx%0Hrk!>HQ4Qz)Ni!T8qfutl6W$HeLr+R#Vh|(<}OO&YQ zn$hyJP4gVzg_ZNCW7FdA@aLb`RBg#_*Rxn}YE`rk6`+%D{)}qdn#o*y+->Y5H0wa< z#Jw^=5A5>h5F0CC@GLtZ4mU7FOViLl?%x@Gy8IFL8v0G1XcmpDWjo-}&eH+7OS>9j z)hL+r)ThN_&BECe!?5Q2xk!l04V7wbOhXUsf(^uIp&f@#0bR81!_-&Wp+yVop-ll( zTbKtg*1&`9yW^hbZ-7V@4b)J)qq`Q@osIOg%{aV&G@?o+Vq1a(ix=wwbqdUdjT;P& z+dDes-7snS)YZM_LQ%RxHt6n@ns0&Am_MaCkdht_;Xu9;PFH(sO5U-QrKRy2x{+aPH0;W98=$*2RZS~TFVzMey1WgJ z>i|ho0Ah?2j&~f?iZyUTD)w&r7Jnv5iL#&8PgiHQ;D zGkq3hxtqa&ehTB?d=?MK>@RkJPQjaARn&N>KK|MHQ}CoUBxhhsuu@0XGbbiuqC(Po!CZ!C=$rZ z8C*Iy6)UGMpht~xuEeB6LK&dzAe!!1D4?&~8HM*|E`j9yhk>b171&B0!}xxk@W}nt zL%Vos=x&13ePiFgXbk*h8t%NiGbE?gbWL5$4?&QTwj3k>+YjBIJs(UDcn#1&qKKm2 zS%!ldQ1^N%DKA=VymD~Ir3q70w!ecB&^)*GJZ6+n^#;(jxoT$k<5%uS`xo9o#cJ`8 zoVEaEiE>kmhLF*ic?Tk`o3Uo`IIQ2Y88zb^NC@3nR6VRN;2jeIojJvM)X=|OUImlB z-wa8rZJ>jwf(Y9|j2-Y4D!h=4gb?y_FFI44Z{kc3MY-0BxV!bos9Li-WJL@}0vgfc z#Q9UdV&~>QIGB3|8+<)9`SzIwwdOwA`NS1L%~wC5YftW`!`*fR6eES zF#8C*5rA%79J=>_eiPKG1K9^(#p9uW4unh|(46K>&k~iFDH^Z~;&n*Q<(M~a6p((X z1Ze9f0y;Cfdjxc`K}$4gwcd3PY?NatfoR!_af3Ue5_IJI5Ai$n{Dh>SehFpKpk+VY z)!;+bxsaH?U(o%5W^vq$4L|n9iA_6$u|IG_zG^jC;dpAAU{5ij0M8NrN^-`wnIHW1 zE2mdGr?d#JhJGtIV(lWLlB?mlS6)YzJ9|QMRx!{E*h|j45=@AeWSrbT7c0N|0?lJC zs9`Jmyy3kZH)zdF1azjM-^NwC-dcBm7xkNrfWyGr32M{?*@jO?bVQ4KS-#6^m;t&< zSUZonOdC3MdJWa@8VXsy!$6BiK?{;5&62^93)r-x2eQc)OzZCmWYh{57YEhhC?-ay zSvF{U4I8*13M3_gqx`hn{fv(^2heF6)BX9p+`VC@W`d{TUy%*kqVs=;ffw7rsU}V{ zN|W(s9`52OH2!oC)_pe?2TrcQ>gf*G%f-pqWg?(64gFSOv-9YfR1t4X`T>%orJ))n zFAylw3QT(CIc(TK<<>_Ty#>&Nn<>tl6?(G`k2t%Cb`L*;S`9yeGp9U==?=E8{Xs~< z#$|)?asO{z(JnsH+_w*Pw>HA#O2`<70WeFuXrv z9()x26y=NG+G+r;d(1zCvJ&P_TRRd&oIBPM=Jg25oh`qYc4R=zi6r8*ReW|({uzimni zc!B10Peby7>G)ypTs(Bo*)Rfja{!%MX$a0@^Qx9O@KZ*yT&n4u08SPmmbO8V%7Kt* zJoH3WG>g3t0^bU}>tpVwPq2v|kT2ZJMp`KxyI~dLT{ic?FHes@sz| z3~e(Mk9HaiM{ZOA_6N;^#|wuszV9oDZNAlL%N@6@XZ?XZ;jBRMJ0us&jlzqMA_C8! z%FW*X`qyVS_!Wmvh2Bu4?GkeVE!iZ*dkczRJfYYI2E77L=}0A59-0hjQgx zLy}4b#c7Vl0rP?r1W8ET@Bxzl+K5_Xvtd_@lo)zK_mN6PH8%&)wNZ1xaoYe=JU1Rf zEZ_ty1i=bXEDeH4$Wk;ExwN{e(^SS<@f94VHX14pDLEL`+_7%(=HLe5+H`yEL9p$GOx0!`8K5;j8~UoNvkazgZg7gSmii%p6%S1yMk~vvvN3 zWuHBQIa4zA1BS^O`l_jegB}gizrPJp4O^kr6Q2Ug-H_$LlwjrfESx+v4nHlPjvv3w z(&yul=XBx%^ys{R&Q?fRQ-D}3yt3iwl?m;>JT%;OVDJynjZG{gL$K|~G~J11^fQN= z;gd3LX!THQ+|yzbpfrReQQ8FhZe7#dM2iGoIEoc>{|}i5e?;B7*F#KOXMnC>+JgV4 zXpxa}dNNL}8>;W_Jims1@)!sSr%Z9a@IVV8Y+4}(Z9B~YNFx(M2tCZl6@_pjX)@L> z`v}WFzYeHZak?J2hRy(87x_Z+CF23z@H_MZ>Y)dQoSKR4@P#PUY5X!;cN_pksT!EY zd)o(U=2)7^OP01{%c{}Xv+@_TXyFVIU}u0H7@0I<6d6|A1^m3`X+)mgZ6Ki6ae3tX zKj+Xex##^3Evwvt1JyBP))d@P?HN}FN^gw0{?LOS?iHLm@-;qq|2C+7NQGm)*PWF7v7}*c8Y90hde}5&wtX5ux1Yl=??z=1n`wa>T zxj1`lI?iq!W{k{~KtR_}ok!fcNVMfCB2I#?Fe#Vc_09_wVHEn&t0t>nfc^VIQ{D4*!hU5sI)0|rLMa)LpxnyxG6y`_djaXT<+KpY-!n&Q89UP3kW8yuvd4iWLOFC(hnDCAs^4uJK} zRf5%W2CM$}8fJ`G<{YtqgJlFL#)NU{Ul2p;O z)SN}nT+24c^SRi!Z4!Q6G6&^wB0$yL7@!x;pU`QcCNSbpVa>OlkdnCHS95K_A5u~^ zbT>upJm^WfL$@{16o~5N3T(E^STS!DX1qI1RXB?9g99BX4;~sRnh@nrI1!s=e74c;EA3S z!1MP8WG|q6wc4&C@wX4Kd&^fysC*45*uhZ+bOneec@oPM&0y9dgekxP-8kmB%dm&&Sbe)6?;A>ih1jn7hx~2UQ zb!DaThdc)8H~2}DZAISmcRbtcOYnT-0EN3Muvi_)O#1>$X1<4*>eQdcW7GoE&;z*g z0yGo@bmIxFm1jM0x*lE`@fIrAcpgq?Sr8={+B*F@0$!9M3RyUFY$1OAVK(YV@5hJ{ zvcH+8@{vvh^wquQKvB9umd#IzX*}=m99s zVmxzPISF7{4~<) zwF<}K%H<#N-NZMsbRjLte2b$T19T&nS7`MS27n&aOmY5lOLLklQzH^h+Ydv%M!g_Q zcR&eBc~D3!b)4%W{gAETo-XhGTzD z#HD=)P_ZISBda${7z1?UWJXU<)cQhs$H8jJ1xPBcWNgHq-)Cdj`aNh-FUvq{Od<0t z*45VZ@Fnj%9PHB~QKn`eG;I1l6gdzjnza(FBKBeTj)6F_evA96g#o(1>so1k+Hg;~AiTf&^Qzz^@u;&4E z(iO7A?$C{0?|DnBYCUUOINh+J77h}{;~?@M_+#TQIJ@f?RE<960&&{9$hc%h+Sj&L~q6DiTyViMsY}&dUtEW3|0Q!x}z5aa| zdpp<^P@|g+sDnuib?ptSK47yi%W%tU=-C=$o!tt z2@OSDKT{9&A9xSdYd--+F5?Po3C=Vro#~xhPR}^= zYWmASXSoj!^$Z@BbHxy;#B+f#;h_)?Y9binI(YsX6p{%k_cAV?K7xxWyP+tFSh)Nk zs*728sP1(%Y{(%#o@(p?0&+JQT!6lcR$D`Dmoun;G@=x-sMX-6W98%_K`)=`-`A)| zF~r#|Xx{K~+}CP66sc}t)<3o2kZU-&YdA`!%;TrfQxL2bY%s)^T*V$z$>qV@fkb!d$S%)yi{G&B6J zQ)N)0a%aT7_7*@Yy3{UH1}w5u8aKk|<23hIG9Mz~36< tfj09&lqh5N%)-d%QpI`xI`(aw^8fPx+(n^>3giF)002ovPDHLkV1mf6Mq~g0 From 83513d8d0566d994927583ed7891c655660af97f Mon Sep 17 00:00:00 2001 From: yashaswini Date: Wed, 1 Apr 2026 02:28:41 +0000 Subject: [PATCH 22/52] RDKEAPPRT-680 :Update new logo --- accelerator-home-ui/static/images/RDKLogo.png | Bin 10347 -> 10835 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/accelerator-home-ui/static/images/RDKLogo.png b/accelerator-home-ui/static/images/RDKLogo.png index 045d6147da790f393134e3d4e6f767d39070c230..d73e15226a4981f76a520e2a68f61e3383eb48b3 100644 GIT binary patch literal 10835 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

D@giENVuig7^WtvF)kAS!CL zesGST=s0o+bQ*!8A@%SgcR_Uq+2%@r7G@cSSo4#ZSvj)Pb~^z{h5)CFRO#g9Dfsvf z3UlV5Xk2}g8R^Vv4+7>D;Bf71Hss8Lzq8-;7P}0kRjsb{caFc^$hsRk zfI#=SrSOnV5dT^hy#Hg%+qai!&i5-0Mpz!fi|-G%r^iVS7y;AEe}m7@4-o2m4Nl6d zz#cC+atJsC;);MMCg;9Mkrx1BcYfCMIIJh< zp-1MqZGDFqE+iTOv*FVU&f)(AXr6=~;d@ay;scnu;6z*I^xH+Cpr9Fbb?*b-Re-Ly zs!Ua&G76#er*X(Kv+cKhq0c$~FOYD@L?O^M^$L4!gEyCRxb1ot@Mdd?Y$@E@55D{q zF`2{>fRHs^PH<-t*vkBQ3-Hchg?s`&3q6dYQOjWd*{!pZ-TkS9KuZH}(a{R`uVeTL%U5tNizUdc@h9HkBdB8rK5pF;dAAov$JZfDu}Uhw1@%w9FZIeyDX zJMo=DpljT03iv;t{urKjIuo>xY>yOSC<+ixy9IMA2HI29O(hE&09giLHgV=0txiF+ z48wqov4}LBjY$48Zd#kn`4Fs~fuFPe{HkKQcWDwY`UQ@G#|Xe$Dy zaX2ye4fxGJ<1L%W_DCTRJ>>rZ00960PNmy<00006Nkl Date: Tue, 31 Mar 2026 22:55:20 -0400 Subject: [PATCH 23/52] RDKEAPPRT-682 Changelog and package config version updates for 6.0.1 Signed-off-by: yashaswini-rk --- CHANGELOG.md | 11 ++++++++++- accelerator-home-ui/settings.json | 2 +- bolt/package-configs/com.rdkcentral.refui.json | 4 ++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3158b91..6afee9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,16 @@ 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). -#### [6.0.0](https://github.com/rdkcentral/rdke-refui/compare/5.0.24...6.0.0) +#### [6.0.1](https://github.com/rdkcentral/rdke-refui/compare/6.0.0...6.0.1) + +- Feature/rdkeapprt 680 :Update to new RDK logos [`#168`](https://github.com/rdkcentral/rdke-refui/pull/168) +- RDKEAPPRT-680 :Update new logo [`83513d8`](https://github.com/rdkcentral/rdke-refui/commit/83513d8d0566d994927583ed7891c655660af97f) +- RDKEAPPRT-680:Update the new logo files [`c2b261f`](https://github.com/rdkcentral/rdke-refui/commit/c2b261ff1ea9e4e72a8750f77652d6f4261775ce) +- Merge tag '6.0.0' into develop [`ff076c2`](https://github.com/rdkcentral/rdke-refui/commit/ff076c212491ba05e68f118666581d41d474f8d3) + +### [6.0.0](https://github.com/rdkcentral/rdke-refui/compare/5.0.24...6.0.0) + +> 31 March 2026 - To refresh the App store and main view when the authentication done [`#166`](https://github.com/rdkcentral/rdke-refui/pull/166) - RDKEAPPRT-661 Add support for new authorization in App Catalog [`#165`](https://github.com/rdkcentral/rdke-refui/pull/165) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 2c24f86..768f608 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.0" + "version": "6.0.1" } } diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 1ae1208..b414e0e 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.0", - "versionName": "6.0.0", + "version": "6.0.1", + "versionName": "6.0.1", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From 5520ae8dcd7d309d172b00fe131707bf3afe1b9b Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 14:32:01 -0400 Subject: [PATCH 24/52] RDKEAPPRT-683: RemoteControl plugin API align with MW APIv3.4.2 --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/api/RemoteControl.js | 42 +++++++++++++++---- .../FactoryResetConfirmationScreen.js | 2 +- .../src/screens/RcInformationScreen.js | 16 +++---- .../screens/SplashScreens/BluetoothScreen.js | 16 +++---- 5 files changed, 53 insertions(+), 25 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 768f608..624fba0 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.1" + "version": "6.0.2" } } diff --git a/accelerator-home-ui/src/api/RemoteControl.js b/accelerator-home-ui/src/api/RemoteControl.js index 1caf9f1..158419e 100644 --- a/accelerator-home-ui/src/api/RemoteControl.js +++ b/accelerator-home-ui/src/api/RemoteControl.js @@ -92,10 +92,9 @@ export default class RCApi { }) } - startPairing(timeout = 30, netType ) { + startPairing(timeout = 30) { return new Promise((resolve, reject) => { - //this.INFO("RCApi: startPairing netType " + netType + " timeout " + timeout); - this.thunder.call('org.rdk.RemoteControl', 'startPairing', { netType: netType, timeout: timeout }).then(result => { + this.thunder.call('org.rdk.RemoteControl', 'startPairing', { timeout: timeout, screenBindEnable:false }).then(result => { //this.INFO("RCApi: startPairing result: ", JSON.stringify(result)) resolve(result.success); }).catch(err => { @@ -103,10 +102,23 @@ export default class RCApi { Metrics.error(Metrics.ErrorType.OTHER,"RemoteControlApiError", "Error in Thunder RemoteControl startPairing "+JSON.stringify(err), false, null) reject(err); }); - resolve(true); }) } + stopPairing() { + return new Promise((resolve, reject) => { + this.INFO("RCApi: stopPairing"); + this.thunder.call('org.rdk.RemoteControl', 'stopPairing', {scanDisable: true}).then(result => { + this.INFO("RCApi: stopPairing result: " + JSON.stringify(result)) + resolve(result.success); + }).catch(err => { + this.ERR("RCApi: stopPairing error: " + JSON.stringify(err)); + Metrics.error(Metrics.ErrorType.OTHER, "RemoteControlApiError", "Error in Thunder RemoteControl stopPairing " + JSON.stringify(err), false, null) + reject(err); + }); + }); + } + initializeIRDB() { return new Promise((resolve, reject) => { /*TODO: implement when requirement comes.*/ @@ -186,10 +198,10 @@ export default class RCApi { }) } - findMyRemote(netType = 1, level = "mid") { + findMyRemote(level = "mid") { return new Promise((resolve, reject) => { - this.INFO("RCApi: findMyRemote netType:" + JSON.stringify(netType) + " level:" + JSON.stringify(level)); - this.thunder.call('org.rdk.RemoteControl', 'findMyRemote', { netType: netType, level: level }).then(result => { + this.INFO("RCApi: findMyRemote level:" + JSON.stringify(level)); + this.thunder.call('org.rdk.RemoteControl', 'findMyRemote', { level: level }).then(result => { this.INFO("RCApi: findMyRemote result: " + JSON.stringify(result)) resolve(result.success); }).catch(err => { @@ -200,6 +212,8 @@ export default class RCApi { }) } + // This is to reset the remote control firmware; not to be confused with factory reset of the device. + // This will not erase user data or settings on the device. factoryReset() { return new Promise((resolve, reject) => { this.INFO("RCApi: factoryReset"); @@ -213,4 +227,18 @@ export default class RCApi { }); }) } + + unpair(macAddressList) { + return new Promise((resolve, reject) => { + this.INFO("RCApi: unpair macAddressList:" + JSON.stringify(macAddressList)); + this.thunder.call('org.rdk.RemoteControl', 'unpair', { macAddressList: macAddressList }).then(result => { + this.INFO("RCApi: unpair result: " + JSON.stringify(result)) + resolve(result.success); + }).catch(err => { + this.ERR("RCApi: unpair error: " + JSON.stringify(err)); + Metrics.error(Metrics.ErrorType.OTHER, "RemoteControlApiError", "Error in Thunder RemoteControl unpair " + JSON.stringify(err), false, null) + reject(err); + }); + }); + } } diff --git a/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js b/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js index 730d7fb..fa94a09 100644 --- a/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js +++ b/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js @@ -211,7 +211,7 @@ export default class RebootConfirmationScreen extends Lightning.Component { try { localStorage.clear(); this.LOG("localStorage cleared successfully"); - } + } catch (err) { this.ERR("Error clearing localStorage: " + JSON.stringify(err)); } diff --git a/accelerator-home-ui/src/screens/RcInformationScreen.js b/accelerator-home-ui/src/screens/RcInformationScreen.js index 03fe522..d382a48 100644 --- a/accelerator-home-ui/src/screens/RcInformationScreen.js +++ b/accelerator-home-ui/src/screens/RcInformationScreen.js @@ -244,16 +244,16 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("SwVersion.Value").text.text = `N/A` this.tag("BatteryPercent.Value").text.text = `N/A` this.tag("RCUName.Value").text.text = `N/A` - //RCApi.get().deactivate().catch(err=> { console.error("RCInformationScreen error:", err)}); } onStatusCB(cbData) { // getStatus response has 'success' property; notification payload does not have that. + // this.LOG("RCInformationScreen onStatusCB cbData:" + JSON.stringify(cbData)); if ((cbData !== undefined) && ("success" in cbData ? cbData.success : true)) { let cbDatastatus if (Array.isArray(cbData.status)) { cbDatastatus = cbData.status[0] || {}; - } + } else if (cbData.status && typeof cbData.status === 'object') { cbDatastatus = cbData.status; } @@ -283,14 +283,14 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("BatteryPercent.Value").text.text = BatteryPercent this.tag("RCUName.Value").text.text = RemoteName } else { - if(cbDatastatus.pairingState != "SEARCHING" && cbDatastatus.pairingState != "PAIRING" ) { - for(let i=0;i { + if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { + // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. + this.scanTrigger && Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = Registry.setTimeout(() => { + RCApi.get().startPairing().catch(err => { this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); }); - } + }, 2000); } } } diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index 847e366..afbb7b2 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -196,13 +196,13 @@ export default class BluetoothScreen extends Lightning.Component { } onStatusCB(cbData) { - //console.log("BluetoothScreen cbData:", JSON.stringify(cbData)); + //console.log("BluetoothScreen cbData:" + JSON.stringify(cbData)); // getStatus response has 'success' property; notification payload does not have that. if ((cbData !== undefined) && (cbData.hasOwnProperty("success") ? cbData.success : true)) { let cbDatastatus if (Array.isArray(cbData.status)) { cbDatastatus = cbData.status[0] || {}; - } + } else if (cbData.status && typeof cbData.status === 'object') { cbDatastatus = cbData.status; } @@ -226,14 +226,14 @@ export default class BluetoothScreen extends Lightning.Component { } }) } else { - if(cbDatastatus.pairingState != "SEARCHING" && cbDatastatus.pairingState != "PAIRING" ) { - for(let i=0;i { + if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { + // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. + this.scanTrigger && Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = Registry.setTimeout(() => { + RCApi.get().startPairing().catch(err => { this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); }); - } + }, 2000); } } } From 47df6367819c67c9bcab0a5ed99fa3007e976d99 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 15:53:36 -0400 Subject: [PATCH 25/52] RDKEAPPRT-683: Fix the RCU pairing trigger timers --- accelerator-home-ui/src/api/RemoteControl.js | 6 +-- accelerator-home-ui/src/routes/routes.js | 2 +- .../src/screens/RcInformationScreen.js | 23 ++++++++---- .../screens/SplashScreens/BluetoothScreen.js | 37 +++++++++++-------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/accelerator-home-ui/src/api/RemoteControl.js b/accelerator-home-ui/src/api/RemoteControl.js index 158419e..0cb6978 100644 --- a/accelerator-home-ui/src/api/RemoteControl.js +++ b/accelerator-home-ui/src/api/RemoteControl.js @@ -94,8 +94,8 @@ export default class RCApi { startPairing(timeout = 30) { return new Promise((resolve, reject) => { - this.thunder.call('org.rdk.RemoteControl', 'startPairing', { timeout: timeout, screenBindEnable:false }).then(result => { - //this.INFO("RCApi: startPairing result: ", JSON.stringify(result)) + this.thunder.call('org.rdk.RemoteControl', 'startPairing', { timeout: timeout, screenBindEnable: false }).then(result => { + this.INFO("RCApi: startPairing result: " + JSON.stringify(result)) resolve(result.success); }).catch(err => { this.ERR("RCApi: startPairing error: " + JSON.stringify(err)); @@ -231,7 +231,7 @@ export default class RCApi { unpair(macAddressList) { return new Promise((resolve, reject) => { this.INFO("RCApi: unpair macAddressList:" + JSON.stringify(macAddressList)); - this.thunder.call('org.rdk.RemoteControl', 'unpair', { macAddressList: macAddressList }).then(result => { + this.thunder.call('org.rdk.RemoteControl', 'unpair', { macAddressList: macAddressList }).then(result => { this.INFO("RCApi: unpair result: " + JSON.stringify(result)) resolve(result.success); }).catch(err => { diff --git a/accelerator-home-ui/src/routes/routes.js b/accelerator-home-ui/src/routes/routes.js index 7f99815..dd67e76 100644 --- a/accelerator-home-ui/src/routes/routes.js +++ b/accelerator-home-ui/src/routes/routes.js @@ -207,7 +207,7 @@ export default { if ("ResidentApp" !== GLOBALS.selfClientName) { Metrics.page(request.hash) .then(success => { - console.log("successfully routed to page ==>", request.hash) + console.log("successfully routed to page ==>" + JSON.stringify(request.hash)) }) .catch(err => console.log("error in metrics.page", err)) } diff --git a/accelerator-home-ui/src/screens/RcInformationScreen.js b/accelerator-home-ui/src/screens/RcInformationScreen.js index d382a48..5b28250 100644 --- a/accelerator-home-ui/src/screens/RcInformationScreen.js +++ b/accelerator-home-ui/src/screens/RcInformationScreen.js @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -import { Lightning, Language, Router } from '@lightningjs/sdk' +import { Lightning, Language, Registry, Router } from '@lightningjs/sdk' import { COLORS } from './../colors/Colors' import { CONFIG } from '../Config/Config' import ThunderJS from 'ThunderJS' @@ -228,6 +228,7 @@ export default class RCInformationScreen extends Lightning.Component { } async _active() { + this.scanTrigger = null; await RCApi.get().activate().catch(err => { this.ERR("RCInformationScreen error: " + JSON.stringify(err)) }); await RCApi.get().getNetStatus().then(result => { this.INFO("RCInformationScreen getNetStatus: " + JSON.stringify(result)) @@ -244,6 +245,9 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("SwVersion.Value").text.text = `N/A` this.tag("BatteryPercent.Value").text.text = `N/A` this.tag("RCUName.Value").text.text = `N/A` + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger); + } } onStatusCB(cbData) { @@ -282,15 +286,20 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("SwVersion.Value").text.text = swVersion this.tag("BatteryPercent.Value").text.text = BatteryPercent this.tag("RCUName.Value").text.text = RemoteName + RCApi.get().findMyRemote().catch(err => { + this.ERR("RCInformationScreen findMyRemote error: " + JSON.stringify(err)) + }); } else { if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. - this.scanTrigger && Registry.clearTimeout(this.scanTrigger); - this.scanTrigger = Registry.setTimeout(() => { - RCApi.get().startPairing().catch(err => { - this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); - }); - }, 2000); + if (!this.scanTrigger) { + this.scanTrigger = Registry.setTimeout(() => { + RCApi.get().startPairing().catch(err => { + this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); + }); + this.scanTrigger = null; + }, 2000); + } } } } diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index afbb7b2..c85d5b1 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -169,23 +169,22 @@ export default class BluetoothScreen extends Lightning.Component { Router.navigate('splash/language') } }) - }) - .catch(err => { - this.ERR(`SplashBluetoothScreen cant stopscan device : ${JSON.stringify(err)}`) - }) - }) .catch(err => { - this.ERR("SplashBluetoothScreen cant stopscan device : " + JSON.stringify(err)) + this.ERR(`SplashBluetoothScreen cant stopscan device : ${JSON.stringify(err)}`) }) }) .catch(err => { - this.ERR("SplashBluetoothScreen cant getpaired device : " + JSON.stringify(err)) + this.ERR("SplashBluetoothScreen cant stopscan device : " + JSON.stringify(err)) }) }) .catch(err => { - this.ERR(`SplashBluetoothScreen Can't pair device : ${JSON.stringify(err)}`) + this.ERR("SplashBluetoothScreen cant getpaired device : " + JSON.stringify(err)) }) + }) + .catch(err => { + this.ERR(`SplashBluetoothScreen Can't pair device : ${JSON.stringify(err)}`) + }) }) }) }) @@ -202,10 +201,10 @@ export default class BluetoothScreen extends Lightning.Component { let cbDatastatus if (Array.isArray(cbData.status)) { cbDatastatus = cbData.status[0] || {}; - } + } else if (cbData.status && typeof cbData.status === 'object') { cbDatastatus = cbData.status; - } + } if (cbDatastatus.remoteData.length) { //console.log("BluetoothScreen rcPairingApis RemoteData Length ", cbData.status.remoteData.length) cbDatastatus.remoteData.map(item => { @@ -228,12 +227,14 @@ export default class BluetoothScreen extends Lightning.Component { } else { if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. - this.scanTrigger && Registry.clearTimeout(this.scanTrigger); - this.scanTrigger = Registry.setTimeout(() => { - RCApi.get().startPairing().catch(err => { - this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); - }); - }, 2000); + if (!this.scanTrigger) { + this.scanTrigger = Registry.setTimeout(() => { + RCApi.get().startPairing().catch(err => { + this.ERR("SplashBluetoothScreen startPairing error: " + JSON.stringify(err)); + }); + this.scanTrigger = null; + }, 2000); + } } } } @@ -280,6 +281,7 @@ export default class BluetoothScreen extends Lightning.Component { _active() { this.initTimer() + this.scanTrigger = null; } pageTransition() { @@ -302,6 +304,9 @@ export default class BluetoothScreen extends Lightning.Component { if (this.RCTimeout) { Registry.clearTimeout(this.RCTimeout) } + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger) + } } static _states() { From 34ee6bea00a1aba71dcbc2e969ef5a6d22f2e94c Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 16:12:46 -0400 Subject: [PATCH 26/52] /RDKEAPPRT-683: stop the scan triggers after RCU pairing --- .../src/screens/RcInformationScreen.js | 17 ++++++++++++++--- .../screens/SplashScreens/BluetoothScreen.js | 14 ++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/accelerator-home-ui/src/screens/RcInformationScreen.js b/accelerator-home-ui/src/screens/RcInformationScreen.js index 5b28250..e1afd8e 100644 --- a/accelerator-home-ui/src/screens/RcInformationScreen.js +++ b/accelerator-home-ui/src/screens/RcInformationScreen.js @@ -235,6 +235,7 @@ export default class RCInformationScreen extends Lightning.Component { onStatusCBhandle = _thunder.on('org.rdk.RemoteControl', 'onStatus', data => { this.onStatusCB(data) }); this.onStatusCB(result); }).catch(err => this.ERR("RCInformationScreen error: " + JSON.stringify(err))); + this.findRemoteTrigger = true; } _inactive() { @@ -247,7 +248,9 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("RCUName.Value").text.text = `N/A` if (this.scanTrigger) { Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = null; } + this.findRemoteTrigger = false; } onStatusCB(cbData) { @@ -286,9 +289,12 @@ export default class RCInformationScreen extends Lightning.Component { this.tag("SwVersion.Value").text.text = swVersion this.tag("BatteryPercent.Value").text.text = BatteryPercent this.tag("RCUName.Value").text.text = RemoteName - RCApi.get().findMyRemote().catch(err => { - this.ERR("RCInformationScreen findMyRemote error: " + JSON.stringify(err)) - }); + if (this.findRemoteTrigger) { + this.findRemoteTrigger = false; + RCApi.get().findMyRemote().catch(err => { + this.ERR("RCInformationScreen findMyRemote error: " + JSON.stringify(err)) + }); + } } else { if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. @@ -300,6 +306,11 @@ export default class RCInformationScreen extends Lightning.Component { this.scanTrigger = null; }, 2000); } + } else if (cbDatastatus.pairingState === "COMPLETE") { + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = null; + } } } } diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index c85d5b1..79d3021 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -135,10 +135,6 @@ export default class BluetoothScreen extends Lightning.Component { } } - _active() { - this.timeout = 30; - } - _PairingApis() { //bluetoothApi.btactivate().then(enableResult =>{ // console.log('1') @@ -175,11 +171,11 @@ export default class BluetoothScreen extends Lightning.Component { }) }) .catch(err => { - this.ERR("SplashBluetoothScreen cant stopscan device : " + JSON.stringify(err)) + this.ERR("SplashBluetoothScreen getpairedDevices failed : " + JSON.stringify(err)) }) }) .catch(err => { - this.ERR("SplashBluetoothScreen cant getpaired device : " + JSON.stringify(err)) + this.ERR("SplashBluetoothScreen getConnectedDevices failed : " + JSON.stringify(err)) }) }) .catch(err => { @@ -235,6 +231,11 @@ export default class BluetoothScreen extends Lightning.Component { this.scanTrigger = null; }, 2000); } + } else if (cbDatastatus.pairingState === "COMPLETE") { + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = null; + } } } } @@ -280,6 +281,7 @@ export default class BluetoothScreen extends Lightning.Component { } _active() { + this.timeout = 30; this.initTimer() this.scanTrigger = null; } From 2610642a37e0d975cfb59ac9d5d4aa498ae4a115 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 19:20:30 -0400 Subject: [PATCH 27/52] RDKEAPPRT-683: fix the RCU re scanning logic leak. --- accelerator-home-ui/src/App.js | 8 ++++- .../src/screens/RcInformationScreen.js | 29 ++++++++++++++++--- .../screens/SplashScreens/BluetoothScreen.js | 27 ++++++++++++++--- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 6a10881..c39a543 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -276,6 +276,12 @@ export default class App extends Router.App { if(GLOBALS.MiracastNotificationstatus && key.keyCode !== Keymap.Power && key.keyCode !== Keymap.Home ){ return false } else if ((key.keyCode == Keymap.Home || key.keyCode == Keymap.Escape) && !Router.isNavigating()) { + if (Router.getActiveHash().startsWith("splash")) { + if (Router.getActiveHash() !== "splash/language") { + Router.navigate("splash/language"); + } + return true; + } if (GLOBALS.topmostApp.includes("dac.native")) { this.jumpToRoute("apps"); } else if (GLOBALS.Miracastclientdevicedetails.state === "INITIATED" || GLOBALS.Miracastclientdevicedetails.state === "INPROGRESS ") { @@ -2868,4 +2874,4 @@ export default class App extends Router.App { } } } -} \ No newline at end of file +} diff --git a/accelerator-home-ui/src/screens/RcInformationScreen.js b/accelerator-home-ui/src/screens/RcInformationScreen.js index e1afd8e..ef9b666 100644 --- a/accelerator-home-ui/src/screens/RcInformationScreen.js +++ b/accelerator-home-ui/src/screens/RcInformationScreen.js @@ -269,6 +269,11 @@ export default class RCInformationScreen extends Lightning.Component { let RemoteName = []; let connectedStatus = []; let MacAddress = []; let swVersion = []; let BatteryPercent = []; + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = null; + } + cbDatastatus.remoteData.map(item => { RemoteName.push(item.name) }) @@ -300,13 +305,29 @@ export default class RCInformationScreen extends Lightning.Component { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. if (!this.scanTrigger) { this.scanTrigger = Registry.setTimeout(() => { - RCApi.get().startPairing().catch(err => { - this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); - }); this.scanTrigger = null; + RCApi.get().getNetStatus().then(result => { + let latestStatus = {}; + if (Array.isArray(result.status)) { + latestStatus = result.status[0] || {}; + } else if (result.status && typeof result.status === 'object') { + latestStatus = result.status; + } + + const latestHasRemoteData = Array.isArray(latestStatus.remoteData) && latestStatus.remoteData.length; + const latestInRetryState = latestStatus.pairingState === "IDLE" || latestStatus.pairingState === "FAILED"; + + if (!latestHasRemoteData && latestInRetryState) { + RCApi.get().startPairing().catch(err => { + this.ERR("RCInformationScreen startPairing error: " + JSON.stringify(err)); + }); + } + }).catch(err => { + this.ERR("RCInformationScreen getNetStatus before startPairing error: " + JSON.stringify(err)); + }); }, 2000); } - } else if (cbDatastatus.pairingState === "COMPLETE") { + } else { if (this.scanTrigger) { Registry.clearTimeout(this.scanTrigger); this.scanTrigger = null; diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index 79d3021..6ae14c5 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -203,6 +203,10 @@ export default class BluetoothScreen extends Lightning.Component { } if (cbDatastatus.remoteData.length) { //console.log("BluetoothScreen rcPairingApis RemoteData Length ", cbData.status.remoteData.length) + if (this.scanTrigger) { + Registry.clearTimeout(this.scanTrigger); + this.scanTrigger = null; + } cbDatastatus.remoteData.map(item => { this.tag('Info').text.text = `paired with device ${item.name}` // Do not clear this.RCTimeout if need to run this in background to reconnect on loss. @@ -225,13 +229,28 @@ export default class BluetoothScreen extends Lightning.Component { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. if (!this.scanTrigger) { this.scanTrigger = Registry.setTimeout(() => { - RCApi.get().startPairing().catch(err => { - this.ERR("SplashBluetoothScreen startPairing error: " + JSON.stringify(err)); - }); this.scanTrigger = null; + RCApi.get().getNetStatus().then(result => { + let latestStatus = {}; + if (Array.isArray(result.status)) { + latestStatus = result.status[0] || {}; + } else if (result.status && typeof result.status === 'object') { + latestStatus = result.status; + } + + const latestHasRemoteData = Array.isArray(latestStatus.remoteData) && latestStatus.remoteData.length; + const latestInRetryState = latestStatus.pairingState === "IDLE" || latestStatus.pairingState === "FAILED"; + if (!latestHasRemoteData && latestInRetryState) { + RCApi.get().startPairing().catch(err => { + this.ERR("SplashBluetoothScreen startPairing error: " + JSON.stringify(err)); + }); + } + }).catch(err => { + this.ERR("SplashBluetoothScreen getNetStatus before startPairing error: " + JSON.stringify(err)); + }); }, 2000); } - } else if (cbDatastatus.pairingState === "COMPLETE") { + } else { if (this.scanTrigger) { Registry.clearTimeout(this.scanTrigger); this.scanTrigger = null; From 791331733db5b5f9876c86bd2f2ab324f7254060 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 19:30:00 -0400 Subject: [PATCH 28/52] RDKEAPPRT-683: fix the alignment issue - this change is introduced to fix the accidental route happening to menu page when RCU key is received from FTU --- accelerator-home-ui/src/App.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index c39a543..2bac5cd 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -276,12 +276,12 @@ export default class App extends Router.App { if(GLOBALS.MiracastNotificationstatus && key.keyCode !== Keymap.Power && key.keyCode !== Keymap.Home ){ return false } else if ((key.keyCode == Keymap.Home || key.keyCode == Keymap.Escape) && !Router.isNavigating()) { - if (Router.getActiveHash().startsWith("splash")) { - if (Router.getActiveHash() !== "splash/language") { - Router.navigate("splash/language"); - } - return true; - } + if (Router.getActiveHash().startsWith("splash")) { + if (Router.getActiveHash() !== "splash/language") { + Router.navigate("splash/language"); + } + return true; + } if (GLOBALS.topmostApp.includes("dac.native")) { this.jumpToRoute("apps"); } else if (GLOBALS.Miracastclientdevicedetails.state === "INITIATED" || GLOBALS.Miracastclientdevicedetails.state === "INPROGRESS ") { From 8add25c150df64f3f9a749d40fe25bbd37466336 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 19:35:26 -0400 Subject: [PATCH 29/52] RDKEAPPRT-683: fix typos and cleanup sequence --- accelerator-home-ui/src/screens/RcInformationScreen.js | 2 +- .../src/screens/SplashScreens/BluetoothScreen.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/accelerator-home-ui/src/screens/RcInformationScreen.js b/accelerator-home-ui/src/screens/RcInformationScreen.js index ef9b666..565303b 100644 --- a/accelerator-home-ui/src/screens/RcInformationScreen.js +++ b/accelerator-home-ui/src/screens/RcInformationScreen.js @@ -229,13 +229,13 @@ export default class RCInformationScreen extends Lightning.Component { async _active() { this.scanTrigger = null; + this.findRemoteTrigger = true; await RCApi.get().activate().catch(err => { this.ERR("RCInformationScreen error: " + JSON.stringify(err)) }); await RCApi.get().getNetStatus().then(result => { this.INFO("RCInformationScreen getNetStatus: " + JSON.stringify(result)) onStatusCBhandle = _thunder.on('org.rdk.RemoteControl', 'onStatus', data => { this.onStatusCB(data) }); this.onStatusCB(result); }).catch(err => this.ERR("RCInformationScreen error: " + JSON.stringify(err))); - this.findRemoteTrigger = true; } _inactive() { diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index 6ae14c5..7f466e9 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -167,7 +167,7 @@ export default class BluetoothScreen extends Lightning.Component { }) }) .catch(err => { - this.ERR(`SplashBluetoothScreen cant stopscan device : ${JSON.stringify(err)}`) + this.ERR(`SplashBluetoothScreen can't stop scan device : ${JSON.stringify(err)}`) }) }) .catch(err => { @@ -327,6 +327,7 @@ export default class BluetoothScreen extends Lightning.Component { } if (this.scanTrigger) { Registry.clearTimeout(this.scanTrigger) + this.scanTrigger = null; } } From 65ec43f96a03810de3254fe283819d5a692d01b9 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 19:42:16 -0400 Subject: [PATCH 30/52] RDKEAPPRT-683: initialize the var declared --- .../src/screens/SplashScreens/BluetoothScreen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index 7f466e9..1672f6d 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -194,7 +194,7 @@ export default class BluetoothScreen extends Lightning.Component { //console.log("BluetoothScreen cbData:" + JSON.stringify(cbData)); // getStatus response has 'success' property; notification payload does not have that. if ((cbData !== undefined) && (cbData.hasOwnProperty("success") ? cbData.success : true)) { - let cbDatastatus + let cbDatastatus = {}; if (Array.isArray(cbData.status)) { cbDatastatus = cbData.status[0] || {}; } From 641dae2c82efa4a64bbc7e54ddb61db6d54236c9 Mon Sep 17 00:00:00 2001 From: Arun Madhavan Date: Thu, 2 Apr 2026 20:05:40 -0400 Subject: [PATCH 31/52] fix(bluetooth-splash): prevent scanTrigger timer race across init/active lifecycle --- .../src/screens/SplashScreens/BluetoothScreen.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index 1672f6d..bafc50e 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -35,6 +35,7 @@ export default class BluetoothScreen extends Lightning.Component { this.LOG = console.log; this.ERR = console.error; this.WARN = console.warn; + this.scanTrigger = null; } static _template() { @@ -201,13 +202,14 @@ export default class BluetoothScreen extends Lightning.Component { else if (cbData.status && typeof cbData.status === 'object') { cbDatastatus = cbData.status; } - if (cbDatastatus.remoteData.length) { + const remoteData = Array.isArray(cbDatastatus.remoteData) ? cbDatastatus.remoteData : []; + if (remoteData.length > 0) { //console.log("BluetoothScreen rcPairingApis RemoteData Length ", cbData.status.remoteData.length) if (this.scanTrigger) { Registry.clearTimeout(this.scanTrigger); this.scanTrigger = null; } - cbDatastatus.remoteData.map(item => { + remoteData.map(item => { this.tag('Info').text.text = `paired with device ${item.name}` // Do not clear this.RCTimeout if need to run this in background to reconnect on loss. // if (this.RCTimeout) { @@ -302,7 +304,9 @@ export default class BluetoothScreen extends Lightning.Component { _active() { this.timeout = 30; this.initTimer() - this.scanTrigger = null; + if (typeof this.scanTrigger === 'undefined') { + this.scanTrigger = null; + } } pageTransition() { From ad290b1fe7f3dbb1754be2dfaf085afeb3db47d3 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Tue, 7 Apr 2026 12:37:44 +0530 Subject: [PATCH 32/52] RDKEAPPRT-687 Changelog updates for 6.0.2 Signed-off-by: suryag23 --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6afee9f..5951c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,21 @@ 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). +#### [6.0.2](https://github.com/rdkcentral/rdke-refui/compare/6.0.1...6.0.2) + +- RDKEAPPRT-683: RemoteControl plugin API align with MW APIv3.4.2 [`#171`](https://github.com/rdkcentral/rdke-refui/pull/171) +- RDKEAPPRT-683: Fix the RCU pairing trigger timers [`47df636`](https://github.com/rdkcentral/rdke-refui/commit/47df6367819c67c9bcab0a5ed99fa3007e976d99) +- RDKEAPPRT-683: fix the RCU re scanning logic leak. [`2610642`](https://github.com/rdkcentral/rdke-refui/commit/2610642a37e0d975cfb59ac9d5d4aa498ae4a115) +- /RDKEAPPRT-683: stop the scan triggers after RCU pairing [`34ee6be`](https://github.com/rdkcentral/rdke-refui/commit/34ee6bea00a1aba71dcbc2e969ef5a6d22f2e94c) + #### [6.0.1](https://github.com/rdkcentral/rdke-refui/compare/6.0.0...6.0.1) +> 31 March 2026 + - Feature/rdkeapprt 680 :Update to new RDK logos [`#168`](https://github.com/rdkcentral/rdke-refui/pull/168) +- RDKEAPPRT-682 Changelog and package config version updates for 6.0.1 [`32bbba6`](https://github.com/rdkcentral/rdke-refui/commit/32bbba6f7cde97607cac613f80240a174073c6bf) - RDKEAPPRT-680 :Update new logo [`83513d8`](https://github.com/rdkcentral/rdke-refui/commit/83513d8d0566d994927583ed7891c655660af97f) - RDKEAPPRT-680:Update the new logo files [`c2b261f`](https://github.com/rdkcentral/rdke-refui/commit/c2b261ff1ea9e4e72a8750f77652d6f4261775ce) -- Merge tag '6.0.0' into develop [`ff076c2`](https://github.com/rdkcentral/rdke-refui/commit/ff076c212491ba05e68f118666581d41d474f8d3) ### [6.0.0](https://github.com/rdkcentral/rdke-refui/compare/5.0.24...6.0.0) From 416c1b35a9b459a6766870964a15de49ad0d246b Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:18:34 +0530 Subject: [PATCH 33/52] Updated the version for refui boltpackage (#175) * Updated the version for refui boltpackage * Updated the version as 6.0.3 --- accelerator-home-ui/settings.json | 2 +- bolt/package-configs/com.rdkcentral.refui.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 624fba0..4c683aa 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.2" + "version": "6.0.3" } } diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index b414e0e..0dc94e8 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.1", - "versionName": "6.0.1", + "version": "6.0.3", + "versionName": "6.0.3", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From a64ad5142fef9c1341028d211ade283bb8d58f5b Mon Sep 17 00:00:00 2001 From: suryag23 Date: Tue, 7 Apr 2026 16:41:30 +0530 Subject: [PATCH 34/52] RDKEAPPRT-688 Changelog updates for 6.0.3 Signed-off-by: suryag23 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5951c6e..6b35ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,15 @@ 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). +#### [6.0.3](https://github.com/rdkcentral/rdke-refui/compare/6.0.2...6.0.3) + +- Updated the version for refui boltpackage [`#175`](https://github.com/rdkcentral/rdke-refui/pull/175) +- Merge tag '6.0.2' into develop [`7d4582c`](https://github.com/rdkcentral/rdke-refui/commit/7d4582c752991e63442df51fecbaf152e355e4c5) + #### [6.0.2](https://github.com/rdkcentral/rdke-refui/compare/6.0.1...6.0.2) +> 7 April 2026 + - RDKEAPPRT-683: RemoteControl plugin API align with MW APIv3.4.2 [`#171`](https://github.com/rdkcentral/rdke-refui/pull/171) - RDKEAPPRT-683: Fix the RCU pairing trigger timers [`47df636`](https://github.com/rdkcentral/rdke-refui/commit/47df6367819c67c9bcab0a5ed99fa3007e976d99) - RDKEAPPRT-683: fix the RCU re scanning logic leak. [`2610642`](https://github.com/rdkcentral/rdke-refui/commit/2610642a37e0d975cfb59ac9d5d4aa498ae4a115) From c638591de6b2761d28262843ceee2416e8a55943 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:17:24 +0530 Subject: [PATCH 35/52] RDKMVE-2127 From Ref UI Home screen, Pressing Volume +/- leads to UI blank in the display (#180) --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 42 +++---------------------------- 2 files changed, 4 insertions(+), 40 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 4c683aa..90202c2 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.3" + "version": "6.0.4" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 2bac5cd..9058ae4 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -395,60 +395,24 @@ export default class App extends Router.App { // Remote power key and keyboard F1 key used for STANDBY and POWER_ON return this._powerKeyPressed() } else if (key.keyCode === Keymap.AudioVolumeMute && !Router.isNavigating()) { - if (GLOBALS.topmostApp === GLOBALS.selfClientName) { + if (GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.tag("Volume").onVolumeMute(); } else { this.LOG("muting on some app") - if (Router.getActiveHash() === "applauncher") { - this.LOG("muting on some app while route is app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - this.tag("Volume").onVolumeMute(); - } else { - this.LOG("muting on some app while route is NOT app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - Router.navigate("applauncher"); - this.tag("Volume").onVolumeMute(); - } } return true } else if (key.keyCode == Keymap.AudioVolumeUp && !Router.isNavigating()) { - if (GLOBALS.topmostApp === GLOBALS.selfClientName) { + if (GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.tag("Volume").onVolumeKeyUp(); } else { this.LOG("muting on some app") - if (Router.getActiveHash() === "applauncher") { - this.LOG("muting on some app while route is app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - this.tag("Volume").onVolumeKeyUp(); - } else { - this.LOG("muting on some app while route is NOT app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - Router.navigate("applauncher"); - this.tag("Volume").onVolumeKeyUp(); - } } return true } else if (key.keyCode == Keymap.AudioVolumeDown && !Router.isNavigating()) { - if (GLOBALS.topmostApp === GLOBALS.selfClientName) { + if (GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.tag("Volume").onVolumeKeyDown(); } else { this.LOG("muting on some app") - if (Router.getActiveHash() === "applauncher") { - this.LOG("muting on some app while route is app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - this.tag("Volume").onVolumeKeyDown(); - } else { - this.LOG("muting on some app while route is NOT app launcher") - RDKShellApis.moveToFront(GLOBALS.selfClientName) - RDKShellApis.setVisibility(GLOBALS.selfClientName, true) - Router.navigate("applauncher"); - this.tag("Volume").onVolumeKeyDown(); - } } return true } else { From 1a7941036f77637eb07bf023f7b37384244f112a Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:51:01 +0530 Subject: [PATCH 36/52] RDKEAPPRT-692 Handle Keycode 8 after Tatlow RCU pairing during FTI toavoid black screen and contain some fix for RCU pairing and powerstate (#181) * RDKEAPPRT-692 Handle Keycode 8 after Tatlow RCU pairing during FTI to avoid black screen * Addressed the review comments * Addressed the review comments --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 52 ++++++++---- .../screens/SplashScreens/BluetoothScreen.js | 84 +++++++++++++++---- 3 files changed, 102 insertions(+), 36 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 90202c2..cfcfd96 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.4" + "version": "6.0.5" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 9058ae4..06d4c9c 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -261,7 +261,7 @@ export default class App extends Router.App { GLOBALS.powerState = PowerState.POWER_STATE_ON; this.LOG("powerState after ===>" + JSON.stringify(GLOBALS.powerState)) this.initializeInactivityEngine(); - }) + }) .catch(err => { this.ERR("Error waking device: " + JSON.stringify(err)); }) @@ -291,7 +291,7 @@ export default class App extends Router.App { } else if(GLOBALS.MiracastNotificationstatus){ this.jumpToRoute("menu"); miracast.acceptClientConnection("Reject").then(res=>{ - if(res.success){Router.focusPage()} + if(res.success){Router.focusPage()} }) } else { this.jumpToRoute("menu"); //method to exit the current app(if any) and route to home screen @@ -487,7 +487,6 @@ export default class App extends Router.App { "Amazon": "n:2", "Prime": "n:2" } - this._getPowerStatebeforeReboot(); // this._registerFireboltListeners() Keyboard.provide('xrn:firebolt:capability:input:keyboard', new KeyboardUIProvider(this)) @@ -511,7 +510,7 @@ export default class App extends Router.App { //https://github.com/rdkcentral/entservices-apis/blob/1.15.11/docs/apis/PowerManagerPlugin.md#setWakeupSrcConfig //By the above documentation we passed the Enum value sum to enable all wakeup sources expect WAKEUP_REASON_UNKNOWN //Enum indicating bit position (bit counting starts at 1) - "wakeupSources": 262143 + "wakeupSources": 262143 } appApi.setWakeupSrcConfiguration(param); appApi.setPowerState(GLOBALS.powerState).then(res => {}); @@ -703,9 +702,11 @@ export default class App extends Router.App { appApi.getPluginStatus('org.rdk.PowerManager').then(result => { if (result && result.length > 0 && result[0].state === "activated") { console.log("org.rdk.PowerManager is already activated"); + this._getPowerStatebeforeReboot(); } else { PowerManagerApi.get().activate().then((res) => { this.LOG("activating the powermanager from app.js " + JSON.stringify(res)) + this._getPowerStatebeforeReboot(); }).catch((err) => this.ERR(JSON.stringify(err))) } }) @@ -813,28 +814,28 @@ export default class App extends Router.App { this._updateLanguageToDefault() // Initialize plugins using the abstraction this._activatePlugin( - "org.rdk.PackageManagerRDKEMS", - "PackageManagerRDKEMS", + "org.rdk.PackageManagerRDKEMS", + "PackageManagerRDKEMS", () => packagemangerRdkems.activate() ); - + this._activatePlugin( - "org.rdk.AppManager", - "AppManager", + "org.rdk.AppManager", + "AppManager", () => AppManager.get().activate(), () => this._SubscribeToAppManagerNotifications() ); - + this._activatePlugin( - "org.rdk.RDKWindowManager", - "RDKWindowManager", + "org.rdk.RDKWindowManager", + "RDKWindowManager", () => RDKWindowManager.get().activate(), () => this._SubscribeToRDKWindowManagerNotifications() ); - + this._activatePlugin( - "org.rdk.RuntimeManager", - "RuntimeManager", + "org.rdk.RuntimeManager", + "RuntimeManager", () => RuntimeManager.get().activate(), () => this._SubscribeToRuntimeManagerNotifications() ); @@ -935,7 +936,7 @@ export default class App extends Router.App { } else { GLOBALS.IsConnectedToInternet = false - } + } console.warn("onInternetStatusChange:", data); }); thunder.on('org.rdk.NetworkManager', 'onAvailableSSIDs', data => { @@ -2112,9 +2113,9 @@ export default class App extends Router.App { appApi.exitApp(currentApp); //will suspend/destroy the app depending on the setting. } Router.navigate('menu'); - } + } else if(notification.newState === PowerState.POWER_STATE_LIGHT_SLEEP && notification.currentState === PowerState.POWER_STATE_DEEP_SLEEP){ - appApi.setPowerState(PowerState.POWER_STATE_ON).then(res => { + appApi.setPowerState(PowerState.POWER_STATE_ON).then(res => { this.LOG("Device woke up from DEEP_SLEEP to LIGHT_SLEEP . setPowerState result: " + JSON.stringify(res)) }).catch(err => { this.ERR("Failed to set power state to ON when device woke up from DEEP_SLEEP to LIGHT_SLEEP. Error: " + JSON.stringify(err)) @@ -2125,6 +2126,21 @@ export default class App extends Router.App { Storage.remove(SLEEP_STATE) } }) + // Catch up: if onPowerModeChanged fired before this listener was registered, + // sync GLOBALS.powerState and Storage(SLEEP_STATE) against live plugin state now. + appApi.getPowerState().then(res => { + if (!res) return; + const liveState = res.currentState; + this.LOG("subscribeToPowerChangeNotifications catch-up getPowerState: " + JSON.stringify(liveState)); + GLOBALS.powerState = liveState; + if (liveState !== PowerState.POWER_STATE_ON) { + Storage.set(SLEEP_STATE, liveState); + } else { + Storage.remove(SLEEP_STATE); + } + }).catch(err => { + this.ERR("subscribeToPowerChangeNotifications catch-up getPowerState error: " + JSON.stringify(err)); + }); } _moveApptoFront(appName, visibility) { diff --git a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js index bafc50e..387485b 100644 --- a/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js +++ b/accelerator-home-ui/src/screens/SplashScreens/BluetoothScreen.js @@ -209,23 +209,22 @@ export default class BluetoothScreen extends Lightning.Component { Registry.clearTimeout(this.scanTrigger); this.scanTrigger = null; } - remoteData.map(item => { + remoteData.forEach(item => { this.tag('Info').text.text = `paired with device ${item.name}` - // Do not clear this.RCTimeout if need to run this in background to reconnect on loss. - // if (this.RCTimeout) { - // console.log("SplashBluetoothScreen clearTimeout(this.RCTimeout)"); - // Registry.clearTimeout(this.RCTimeout) - // } - // To stop the display counter. - if (Router.getActiveHash() === "splash/bluetooth") { - if (this.timeInterval) { - Registry.clearInterval(this.timeInterval) - } - Registry.setTimeout(() => { - Router.navigate('splash/language') - }, 2000) - } }) + // To stop the display counter and navigate once. + if (Router.getActiveHash() === "splash/bluetooth") { + if (this.timeInterval) { + Registry.clearInterval(this.timeInterval) + } + if (this.navigateTimeout) { + Registry.clearTimeout(this.navigateTimeout); + } + this.navigateTimeout = Registry.setTimeout(() => { + this.navigateTimeout = null; + Router.navigate('splash/language') + }, 2000) + } } else { if (cbDatastatus.pairingState === "IDLE" || cbDatastatus.pairingState === "FAILED") { // after 2 seconds, initiate pairing flow if status is IDLE, as there is no paired device. @@ -243,7 +242,17 @@ export default class BluetoothScreen extends Lightning.Component { const latestHasRemoteData = Array.isArray(latestStatus.remoteData) && latestStatus.remoteData.length; const latestInRetryState = latestStatus.pairingState === "IDLE" || latestStatus.pairingState === "FAILED"; if (!latestHasRemoteData && latestInRetryState) { - RCApi.get().startPairing().catch(err => { + RCApi.get().startPairing().then(success => { + if (success === false && !this.scanTrigger) { + this.ERR("SplashBluetoothScreen startPairing returned false, retrying..."); + this.scanTrigger = Registry.setTimeout(() => { + this.scanTrigger = null; + RCApi.get().startPairing().catch(err => { + this.ERR("SplashBluetoothScreen startPairing retry error: " + JSON.stringify(err)); + }); + }, 2000); + } + }).catch(err => { this.ERR("SplashBluetoothScreen startPairing error: " + JSON.stringify(err)); }); } @@ -271,7 +280,39 @@ export default class BluetoothScreen extends Lightning.Component { } _thunder.on('org.rdk.RemoteControl', 'onStatus', data => { this.onStatusCB(data) }); this.RCTimeout = Registry.setTimeout(() => { - RCApi.get().getNetStatus().then(result => { this.onStatusCB(result); }); + RCApi.get().getNetStatus().then(result => { + this.onStatusCB(result); + // onStatusCB only schedules startPairing on IDLE/FAILED. If the plugin + // auto-started a PAIRING session (state="PAIRING"), onStatusCB clears + // scanTrigger without scheduling anything, causing a ~30s delay until + // the session expires. If no device is paired and no scanTrigger was set, + // ensure startPairing is called within 5 seconds of page load. + if (!this.scanTrigger) { + let status = Array.isArray(result.status) ? (result.status[0] || {}) : + (result.status && typeof result.status === 'object' ? result.status : {}); + const hasRemote = Array.isArray(status.remoteData) && status.remoteData.length > 0; + const inRetryState = status.pairingState === "IDLE" || status.pairingState === "FAILED"; + if (!hasRemote && inRetryState) { + this.scanTrigger = Registry.setTimeout(() => { + this.scanTrigger = null; + RCApi.get().startPairing().catch(err => { + this.ERR("SplashBluetoothScreen startPairing error: " + JSON.stringify(err)); + }); + }, 3000); + } + } + }).catch(err => { + this.ERR("SplashBluetoothScreen getNetStatus error: " + JSON.stringify(err)); + // On failure, schedule startPairing as a recovery so pairing doesn't stall. + if (!this.scanTrigger) { + this.scanTrigger = Registry.setTimeout(() => { + this.scanTrigger = null; + RCApi.get().startPairing().catch(pairErr => { + this.ERR("SplashBluetoothScreen startPairing after getNetStatus failure error: " + JSON.stringify(pairErr)); + }); + }, 3000); + } + }); }, 5, true); } @@ -309,6 +350,11 @@ export default class BluetoothScreen extends Lightning.Component { } } + _handleBack() { + // Block back navigation during splash setup to prevent black screen. + return true; + } + pageTransition() { return 'left' } @@ -333,6 +379,10 @@ export default class BluetoothScreen extends Lightning.Component { Registry.clearTimeout(this.scanTrigger) this.scanTrigger = null; } + if (this.navigateTimeout) { + Registry.clearTimeout(this.navigateTimeout) + this.navigateTimeout = null; + } } static _states() { From 94450276aacf4ea3b57c583f0faba70c37802d12 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Wed, 15 Apr 2026 09:42:17 +0530 Subject: [PATCH 37/52] RDKEAPPRT-684 Sleep Timer and Screen-Saver is not working (#182) * RDKEAPPRT-684 Sleep Timer and Screen-Saver is not working * Addressed the review comments * Addressed the review comments --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 36 +++++++++++-------- .../src/helpers/InactivityHelper.js | 26 +++++++++++--- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index cfcfd96..0a669d8 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.5" + "version": "6.0.6" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 06d4c9c..43145b4 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -1738,7 +1738,7 @@ export default class App extends Router.App { if (!hasValidTimer) { this.LOG('No valid inactivity timers found. Disabling inactivity reporting.'); - RDKShellApis.enableInactivityReporting(false) + appApi.enableInactivityReporting(false) .catch(err => this.ERR('Error disabling inactivity: ' + JSON.stringify(err))); return; } @@ -1755,10 +1755,11 @@ export default class App extends Router.App { } } - registerOnUserInactivityListener() { - thunder.Controller.activate({ callsign: 'org.rdk.RDKShell.1' }).then(res => { - this.LOG("RDKShell activated, trying to set the inactivity listener; res = " + JSON.stringify(res)); - thunder.on("org.rdk.RDKShell.1", "onUserInactivity", async notification => { + async registerOnUserInactivityListener() { + try { + const res = await thunder.Controller.activate({ callsign: 'org.rdk.RDKWindowManager' }); + this.LOG("RDKWindowManager activated, trying to set the inactivity listener; res = " + JSON.stringify(res)); + thunder.on("org.rdk.RDKWindowManager", "onUserInactivity", async notification => { const { energySaver, screenSaver, sleepTimer } = inactivityHelper.getInactivityConfig(); const minutes = Math.floor(Number(notification.minutes)); @@ -1773,7 +1774,7 @@ export default class App extends Router.App { if (inactivityHelper.isValidTimeout(sleepTimer) && minutes === sleepTimer) { this.LOG('Sleep Timer triggered'); this.currentStage = 'SleepTimer'; - if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfClientName) { + if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfclientAppName) { inactivityHelper.standby('STANDBY'); } } @@ -1781,19 +1782,22 @@ export default class App extends Router.App { if (inactivityHelper.isValidTimeout(energySaver) && minutes === energySaver) { this.LOG('Energy saver triggered'); this.currentStage = 'EnergySaver'; - if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfClientName) { + if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.LOG("Going to sleep due to inactivity"); inactivityHelper._enterSleepMode(); } } }, err => this.ERR("Listener error: " + JSON.stringify(err))); - }) + } catch (err) { + this.ERR("Failed to activate RDKWindowManager for inactivity listener: " + JSON.stringify(err)); + throw err; + } } async triggerScreensaver() { const result = await appApi.getAvCodeStatus(); if (["IDLE", "PAUSE"].includes(result.avDecoderStatus) && - GLOBALS.topmostApp === GLOBALS.selfClientName) { + GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.$hideImage(1); } return result; @@ -1814,15 +1818,19 @@ export default class App extends Router.App { this.currentInterval = screenSaver; } - RDKShellApis.enableInactivityReporting(true) - .then(() => RDKShellApis.setInactivityInterval(this.currentInterval)) - .then(() => { + appApi.enableInactivityReporting(true) + .then(() => appApi.setInactivityInterval(this.currentInterval)) + .then(async () => { this.LOG(`Inactivity interval set to ${this.currentInterval} for stage=${this.currentStage}`) if (!this.thunderListenerRegistered) { this.LOG("Registering listener for inactivity events..."); - this.registerOnUserInactivityListener(); - this.thunderListenerRegistered = true; + try { + await this.registerOnUserInactivityListener(); + this.thunderListenerRegistered = true; + } catch (err) { + this.ERR("Inactivity listener registration failed, will retry on next interval set: " + JSON.stringify(err)); + } } }) .catch(err => this.ERR("setInactivityIntervalStage error: " + JSON.stringify(err))); diff --git a/accelerator-home-ui/src/helpers/InactivityHelper.js b/accelerator-home-ui/src/helpers/InactivityHelper.js index 53d6094..d9d3c91 100644 --- a/accelerator-home-ui/src/helpers/InactivityHelper.js +++ b/accelerator-home-ui/src/helpers/InactivityHelper.js @@ -18,9 +18,9 @@ **/ import { Router, Storage } from '@lightningjs/sdk'; import AppApi from '../api/AppApi.js'; -import RDKShellApis from '../api/RDKShellApis.js'; import { GLOBALS } from '../Config/Config.js'; import { PowerState } from '../api/PowerManagerApi.js'; +import AppManager from '../api/AppManagerApi.js'; var appApi = new AppApi(); @@ -70,7 +70,7 @@ export default class InactivityHelper { if (activeStages.length === 0) { this.LOG('No active timers left. Disabling inactivity reporting.'); - RDKShellApis.enableInactivityReporting(false) + appApi.enableInactivityReporting(false) .catch(err => this.ERR('Error disabling inactivity: ' + JSON.stringify(err))); } else { this.LOG(`Stage ${stage} cleared, but ${activeStages.join(', ')} still active.`); @@ -110,8 +110,23 @@ export default class InactivityHelper { if (res) { this.LOG("successfully set to standby"); GLOBALS.powerState = PowerState.POWER_STATE_STANDBY - if (GLOBALS.topmostApp !== GLOBALS.selfClientName) { - appApi.exitApp(GLOBALS.topmostApp); + if (GLOBALS.topmostApp !== GLOBALS.selfclientAppName) { + const targetApp = GLOBALS.topmostApp; + AppManager.get().closeApp(targetApp).then(() => { + this.LOG("closeApp success for: " + targetApp); + AppManager.get().terminateApp(targetApp).then(() => { + this.LOG("terminateApp success after closeApp for: " + targetApp); + }).catch(err => { + this.ERR("terminateApp err after closeApp: " + JSON.stringify(err)); + }); + }).catch(err => { + this.ERR("closeApp err for " + targetApp + ": " + JSON.stringify(err)); + AppManager.get().terminateApp(targetApp).then(() => { + this.LOG("terminateApp success after closeApp failure for: " + targetApp); + }).catch(termErr => { + this.ERR("terminateApp err after closeApp failure for " + targetApp + ": " + JSON.stringify(termErr)); + }); + }); } else { if (!Router.isNavigating()) { Router.navigate('menu') @@ -119,6 +134,9 @@ export default class InactivityHelper { } } }) + .catch(err => { + this.ERR("setPowerState error during standby: " + JSON.stringify(err)); + }); return true } } From 6fefb0eec9c858c0dda2d9a0c6fc98f5744920e4 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:07:50 +0530 Subject: [PATCH 38/52] RDKEAPPRT-695 Incorrect IP address displayed on Network Info page after network reconnection and package version update for refui and wpe (#183) * RDKEAPPRT-695 Incorrect IP address displayed on Network Info page after network reconnection and package version update for refui and wpe * Addrressed the review comments * Addressed the review comments --- accelerator-home-ui/settings.json | 2 +- .../NetworkScreens/NetworkInfoScreen.js | 89 +++++-------------- .../OtherSettingsScreens/NetworkInfoScreen.js | 83 ++++------------- .../package-configs/com.rdkcentral.refui.json | 6 +- 4 files changed, 44 insertions(+), 136 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 0a669d8..b4656a3 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.6" + "version": "6.0.7" } } diff --git a/accelerator-home-ui/src/overlays/NetworkScreens/NetworkInfoScreen.js b/accelerator-home-ui/src/overlays/NetworkScreens/NetworkInfoScreen.js index 5c6b251..40d59b7 100644 --- a/accelerator-home-ui/src/overlays/NetworkScreens/NetworkInfoScreen.js +++ b/accelerator-home-ui/src/overlays/NetworkScreens/NetworkInfoScreen.js @@ -290,55 +290,10 @@ export default class NetworkInfo extends Lightning.Component { this.tag("IPAddress.Value").text.text = `NA` this.tag("Gateway.Value").text.text = `NA` this.tag("MACAddress.Value").text.text = `NA` - if ("ResidentApp" === GLOBALS.selfClientName) - { - await NetworkManager.GetPrimaryInterface().then((defaultInterface) => { - console.log("defaultinterface"+defaultInterface) - NetworkManager.GetIPSettings(defaultInterface).then((result) => { - if (result.interface === "wlan0") { - this.tag("ConnectionType.Value").text.text = Language.translate("Wireless") - this.tag("SSID").alpha = 1 - this.tag("SignalStrength").alpha = 1 - NetworkManager.GetConnectedSSID().then((result) => { - if (parseInt(result.strength) >= -50) { - this.tag("SignalStrength.Value").text.text = `Excellent` - } - else if (parseInt(result.strength) >= -60) { - this.tag("SignalStrength.Value").text.text = `Good` - } - else if (parseInt(result.strength) >= -67) { - this.tag("SignalStrength.Value").text.text = `Fair` - } - else { - this.tag("SignalStrength.Value").text.text = `Poor` - } - this.tag("SSID.Value").text.text = `${result.ssid}` - }).catch((error) => console.log(error)); - } else if (result.interface === "eth0") { - this.tag("ConnectionType.Value").text.text = 'Ethernet' - this.tag("SSID").alpha = 0 - this.tag("SignalStrength").alpha = 0 - } - this.tag('InternetProtocol.Value').text.text = result.ipversion - this.tag('IPAddress.Value').text.text = result.ipaddress - this.tag("Gateway.Value").text.text = result.gateway - }).catch((err) => console.error(err)) - - NetworkManager.GetAvailableInterfaces().then((interfaces) => { - currentInterface = interfaces.filter((data) => data.name === defaultInterface) - if (currentInterface[0].connected) { - this.tag("Status.Value").text.text = Language.translate('Connected') - } - else { - this.tag('Status.Value').text.text = Language.translate('Disconnected') - } - this.tag('MACAddress.Value').text.text = currentInterface[0].mac - }).catch((error) => console.log(error)); - }).catch((error) => console.log(error)); - } - else{ - await FireBoltApi.get().deviceinfo.getnetwork().then(res=>{ - if (res.type === "wifi") { + await NetworkManager.GetPrimaryInterface().then((defaultInterface) => { + console.log("defaultinterface"+defaultInterface) + NetworkManager.GetIPSettings(defaultInterface).then((result) => { + if (result.interface === "wlan0") { this.tag("ConnectionType.Value").text.text = Language.translate("Wireless") this.tag("SSID").alpha = 1 this.tag("SignalStrength").alpha = 1 @@ -356,34 +311,32 @@ export default class NetworkInfo extends Lightning.Component { this.tag("SignalStrength.Value").text.text = `Poor` } this.tag("SSID.Value").text.text = `${result.ssid}` - }).catch((error) => { - this.ERR("WiFi.get().getConnectedSSID error: " + JSON.stringify(error)) - }); - } else if (res.type === "ethernet") { + }).catch((error) => this.ERR("GetConnectedSSID error: " + JSON.stringify(error))); + } else if (result.interface === "eth0") { this.tag("ConnectionType.Value").text.text = 'Ethernet' this.tag("SSID").alpha = 0 this.tag("SignalStrength").alpha = 0 } - if (res.state== "connected") { + this.tag('InternetProtocol.Value').text.text = result.ipversion + this.tag('IPAddress.Value').text.text = result.ipaddress + this.tag("Gateway.Value").text.text = result.gateway + }).catch((err) => this.ERR("GetIPSettings error: " + JSON.stringify(err))) + + NetworkManager.GetAvailableInterfaces().then((interfaces) => { + const matchedInterface = interfaces.find((data) => data.name === defaultInterface) + if (!matchedInterface) { + this.ERR("Interface not found for: " + defaultInterface) + return + } + if (matchedInterface.connected) { this.tag("Status.Value").text.text = Language.translate('Connected') } else { this.tag('Status.Value').text.text = Language.translate('Disconnected') } - NetworkManager.GetPrimaryInterface().then((defaultInterface) => { - NetworkManager.GetIPSettings(defaultInterface).then((result) => { - this.tag('InternetProtocol.Value').text.text = result.ipversion - this.tag('IPAddress.Value').text.text = result.ipaddress - this.tag("Gateway.Value").text.text = result.gateway - }) - NetworkManager.GetAvailableInterfaces().then((res) => { - currentInterface = res.interfaces.filter((data) => data.type === defaultInterface) - this.tag('MACAddress.Value').text.text = currentInterface[0].mac - }).catch((error) => console.log(error)); - }) - - }).catch((error) => console.log(error)); - } + this.tag('MACAddress.Value').text.text = matchedInterface.mac + }).catch((error) => this.ERR("GetAvailableInterfaces error: " + JSON.stringify(error))); + }).catch((error) => this.ERR("GetPrimaryInterface error: " + JSON.stringify(error))); } _focus() { diff --git a/accelerator-home-ui/src/screens/OtherSettingsScreens/NetworkInfoScreen.js b/accelerator-home-ui/src/screens/OtherSettingsScreens/NetworkInfoScreen.js index 568cdad..dcd58b7 100644 --- a/accelerator-home-ui/src/screens/OtherSettingsScreens/NetworkInfoScreen.js +++ b/accelerator-home-ui/src/screens/OtherSettingsScreens/NetworkInfoScreen.js @@ -309,55 +309,10 @@ export default class NetworkInfo extends Lightning.Component { this.tag("IPAddress.Value").text.text = `NA` this.tag("Gateway.Value").text.text = `NA` this.tag("MACAddress.Value").text.text = `NA` - if ("ResidentApp" === GLOBALS.selfClientName) - { - await NetworkManager.GetPrimaryInterface().then((defaultInterface) => { - console.log("defaultinterface"+defaultInterface) - NetworkManager.GetIPSettings(defaultInterface).then((result) => { - if (result.interface === "wlan0") { - this.tag("ConnectionType.Value").text.text = Language.translate("Wireless") - this.tag("SSID").alpha = 1 - this.tag("SignalStrength").alpha = 1 - NetworkManager.GetConnectedSSID().then((result) => { - if (parseInt(result.strength) >= -50) { - this.tag("SignalStrength.Value").text.text = `Excellent` - } - else if (parseInt(result.strength) >= -60) { - this.tag("SignalStrength.Value").text.text = `Good` - } - else if (parseInt(result.strength) >= -67) { - this.tag("SignalStrength.Value").text.text = `Fair` - } - else { - this.tag("SignalStrength.Value").text.text = `Poor` - } - this.tag("SSID.Value").text.text = `${result.ssid}` - }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - } else if (result.interface === "eth0") { - this.tag("ConnectionType.Value").text.text = 'Ethernet' - this.tag("SSID").alpha = 0 - this.tag("SignalStrength").alpha = 0 - } - this.tag('InternetProtocol.Value').text.text = result.ipversion - this.tag('IPAddress.Value').text.text = result.ipaddress - this.tag("Gateway.Value").text.text = result.gateway - }).catch((err) => this.ERR("Error: " + JSON.stringify(err))) - - NetworkManager.GetAvailableInterfaces().then((interfaces) => { - currentInterface = interfaces.filter((data) => data.name === defaultInterface) - if (currentInterface[0].connected) { - this.tag("Status.Value").text.text = Language.translate('Connected') - } - else { - this.tag('Status.Value').text.text = Language.translate('Disconnected') - } - this.tag('MACAddress.Value').text.text = currentInterface[0].mac - }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - } - else{ - await FireBoltApi.get().deviceinfo.getnetwork().then(res=>{ - if (res.type === "wifi") { + await NetworkManager.GetPrimaryInterface().then((defaultInterface) => { + console.log("defaultinterface"+defaultInterface) + NetworkManager.GetIPSettings(defaultInterface).then((result) => { + if (result.interface === "wlan0") { this.tag("ConnectionType.Value").text.text = Language.translate("Wireless") this.tag("SSID").alpha = 1 this.tag("SignalStrength").alpha = 1 @@ -376,31 +331,31 @@ export default class NetworkInfo extends Lightning.Component { } this.tag("SSID.Value").text.text = `${result.ssid}` }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - } else if (res.type === "ethernet") { + } else if (result.interface === "eth0") { this.tag("ConnectionType.Value").text.text = 'Ethernet' this.tag("SSID").alpha = 0 this.tag("SignalStrength").alpha = 0 } - if (res.state== "connected") { + this.tag('InternetProtocol.Value').text.text = result.ipversion + this.tag('IPAddress.Value').text.text = result.ipaddress + this.tag("Gateway.Value").text.text = result.gateway + }).catch((err) => this.ERR("Error: " + JSON.stringify(err))) + + NetworkManager.GetAvailableInterfaces().then((interfaces) => { + const matchedInterface = interfaces.find((data) => data.name === defaultInterface) + if (!matchedInterface) { + this.ERR("Interface not found for: " + defaultInterface) + return + } + if (matchedInterface.connected) { this.tag("Status.Value").text.text = Language.translate('Connected') } else { this.tag('Status.Value').text.text = Language.translate('Disconnected') } - NetworkManager.GetPrimaryInterface().then((defaultInterface) => { - NetworkManager.GetIPSettings(defaultInterface).then((result) => { - this.tag('InternetProtocol.Value').text.text = result.ipversion - this.tag('IPAddress.Value').text.text = result.ipaddress - this.tag("Gateway.Value").text.text = result.gateway - }) - NetworkManager.GetAvailableInterfaces().then((res) => { - currentInterface = res.interfaces.filter((data) => data.type === defaultInterface) - this.tag('MACAddress.Value').text.text = currentInterface[0].mac - }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - }) - + this.tag('MACAddress.Value').text.text = matchedInterface.mac }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); - } + }).catch((error) => this.ERR("Error: " + JSON.stringify(error))); } _focus() { diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 0dc94e8..6a7b48c 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,12 +1,12 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.3", - "versionName": "6.0.3", + "version": "6.0.7", + "versionName": "6.0.7", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", "dependencies": { - "com.rdkcentral.wpe": "0.2.0" + "com.rdkcentral.wpe": "0.3.0" }, "permissions": [ "urn:rdk:permission:home-app", From 4b1d5bef54924bfa99e6a8a62003e155db98b7b4 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Fri, 17 Apr 2026 15:26:43 +0530 Subject: [PATCH 39/52] RDKEAPPRT-705 Changelog updates for 6.0.7 Signed-off-by: suryag23 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b35ff0..c5e7c8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,20 @@ 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). +#### [6.0.7](https://github.com/rdkcentral/rdke-refui/compare/6.0.3...6.0.7) + +- RDKEAPPRT-695 Incorrect IP address displayed on Network Info page after network reconnection and package version update for refui and wpe [`#183`](https://github.com/rdkcentral/rdke-refui/pull/183) +- RDKEAPPRT-684 Sleep Timer and Screen-Saver is not working [`#182`](https://github.com/rdkcentral/rdke-refui/pull/182) +- RDKEAPPRT-692 Handle Keycode 8 after Tatlow RCU pairing during FTI toavoid black screen and contain some fix for RCU pairing and powerstate [`#181`](https://github.com/rdkcentral/rdke-refui/pull/181) +- RDKMVE-2127 From Ref UI Home screen, Pressing Volume +/- leads to UI blank in the display [`#180`](https://github.com/rdkcentral/rdke-refui/pull/180) +- Merge tag '6.0.3' into develop [`c6030f2`](https://github.com/rdkcentral/rdke-refui/commit/c6030f2f54ffc42cd26e0e96688a41b460c13590) + #### [6.0.3](https://github.com/rdkcentral/rdke-refui/compare/6.0.2...6.0.3) +> 7 April 2026 + - Updated the version for refui boltpackage [`#175`](https://github.com/rdkcentral/rdke-refui/pull/175) +- RDKEAPPRT-688 Changelog updates for 6.0.3 [`a64ad51`](https://github.com/rdkcentral/rdke-refui/commit/a64ad5142fef9c1341028d211ade283bb8d58f5b) - Merge tag '6.0.2' into develop [`7d4582c`](https://github.com/rdkcentral/rdke-refui/commit/7d4582c752991e63442df51fecbaf152e355e4c5) #### [6.0.2](https://github.com/rdkcentral/rdke-refui/compare/6.0.1...6.0.2) From b240acb04e4e7cad494e736445f7378bf1e7d944 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Mon, 20 Apr 2026 17:59:40 +0530 Subject: [PATCH 40/52] RDKMVE-1860 Guide page is not loading and RDKEAPPRT-693 Wakesrc LAN is not set by default (#186) * RDKMVE-1860 Guide page is not loading and RDKEAPPRT-693 Wakesrc LAN is not set by default * To update the version to 6.0.8 for release --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 39 ++++++++++++------- accelerator-home-ui/src/api/AppApi.js | 4 +- .../src/api/PowerManagerApi.js | 12 +++--- accelerator-home-ui/src/views/Menu.js | 8 ++-- .../static/data/SidePanelInfo.js | 8 ++-- .../package-configs/com.rdkcentral.refui.json | 4 +- 7 files changed, 43 insertions(+), 34 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index b4656a3..e0b8e07 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.7" + "version": "6.0.8" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 43145b4..cb52da9 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -502,21 +502,6 @@ export default class App extends Router.App { Storage.set("deviceType", ((result.devicetype != null) ? result.devicetype : "IpTv")); }); UserSettingsApi.get().activate(); - thunder.Controller.activate({ - callsign: 'org.rdk.System' - }).then(result => { - this.LOG("App System plugin activation result: " + JSON.stringify(result)) - let param = { - //https://github.com/rdkcentral/entservices-apis/blob/1.15.11/docs/apis/PowerManagerPlugin.md#setWakeupSrcConfig - //By the above documentation we passed the Enum value sum to enable all wakeup sources expect WAKEUP_REASON_UNKNOWN - //Enum indicating bit position (bit counting starts at 1) - "wakeupSources": 262143 - } - appApi.setWakeupSrcConfiguration(param); - appApi.setPowerState(GLOBALS.powerState).then(res => {}); - }).catch(err => { - this.ERR("App System plugin activation error: " + JSON.stringify(err)); - }) appApi.getPluginStatus("org.rdk.DeviceDiagnostics").then(res => { this.LOG("App DeviceDiagnostics state:" + JSON.stringify(res[0].state)) if (res[0].state === "deactivated") { @@ -703,10 +688,12 @@ export default class App extends Router.App { if (result && result.length > 0 && result[0].state === "activated") { console.log("org.rdk.PowerManager is already activated"); this._getPowerStatebeforeReboot(); + this._setWakeupSourceConfig(); } else { PowerManagerApi.get().activate().then((res) => { this.LOG("activating the powermanager from app.js " + JSON.stringify(res)) this._getPowerStatebeforeReboot(); + this._setWakeupSourceConfig(); }).catch((err) => this.ERR(JSON.stringify(err))) } }) @@ -1672,6 +1659,28 @@ export default class App extends Router.App { } } + _setWakeupSourceConfig() { + //https://jira.rdkcentral.com/jira/browse/RDKEAPPRT-693 + //by the above jira, we need to enable all wakeup sources in order to wake up the device from standby using any source. So enabling all the wakeup sources here. + let param = { + "wakeupSources": [ + {"wakeupSource": "VOICE", "enabled": true}, + {"wakeupSource": "IR", "enabled": true}, + {"wakeupSource": "CEC", "enabled": true}, + {"wakeupSource": "BLUETOOTH", "enabled": true}, + {"wakeupSource": "WIFI", "enabled": true}, + {"wakeupSource": "LAN", "enabled": true}, + {"wakeupSource": "POWERKEY", "enabled": true}, + ] + } + this.LOG("_setWakeupSourceConfig: Calling with param: " + JSON.stringify(param)) + appApi.setWakeupSourceConfig(param).then(res => { + this.LOG("_setWakeupSourceConfig: Successfully set wakeup source config: " + JSON.stringify(res)) + }).catch(err => { + this.ERR("_setWakeupSourceConfig: Error setting wakeup source config: " + JSON.stringify(err)) + }) + } + _getPowerStatebeforeReboot() { appApi.getPowerStateBeforeReboot().then(res => { this.LOG("_getPowerStatebeforeReboot: getpowerstate before reboot " + JSON.stringify(res)); diff --git a/accelerator-home-ui/src/api/AppApi.js b/accelerator-home-ui/src/api/AppApi.js index c1d5f45..eb0005b 100644 --- a/accelerator-home-ui/src/api/AppApi.js +++ b/accelerator-home-ui/src/api/AppApi.js @@ -1623,8 +1623,8 @@ export default class AppApi { }) } - setWakeupSrcConfiguration(params) { - return PowerManagerApi.get().setWakeupSrcConfig(params) + setWakeupSourceConfig(params) { + return PowerManagerApi.get().setWakeupSourceConfig(params) } async sendAppState(value) { diff --git a/accelerator-home-ui/src/api/PowerManagerApi.js b/accelerator-home-ui/src/api/PowerManagerApi.js index 744260e..9153fe2 100644 --- a/accelerator-home-ui/src/api/PowerManagerApi.js +++ b/accelerator-home-ui/src/api/PowerManagerApi.js @@ -85,15 +85,15 @@ export default class PowerManagerApi { }) } - setWakeupSrcConfig(params) { - this.LOG("setWakeupSrcConfiguration params:", JSON.stringify(params)); + setWakeupSourceConfig(params) { + this.LOG("setWakeupSourceConfig params:", JSON.stringify(params)); return new Promise((resolve, reject) => { - this.thunder.call(this.callsign, 'setWakeupSrcConfig', params).then(result => { - this.LOG(" setWakeupSrcConfiguration result:", JSON.stringify(result)) + this.thunder.call(this.callsign, 'setWakeupSourceConfig', params).then(result => { + this.LOG(" setWakeupSourceConfig result:", JSON.stringify(result)) resolve(result) }).catch(err => { - this.ERR(" setWakeupSrcConfiguration error:", JSON.stringify(err)) - Metrics.error(Metrics.ErrorType.OTHER, "PluginError", "Error in Thunder system setWakeupSrcConfiguration " + JSON.stringify(err), false, null) + this.ERR(" setWakeupSourceConfig error:", JSON.stringify(err)) + Metrics.error(Metrics.ErrorType.OTHER, "PluginError", "Error in Thunder system setWakeupSourceConfig " + JSON.stringify(err), false, null) reject(err) }) }) diff --git a/accelerator-home-ui/src/views/Menu.js b/accelerator-home-ui/src/views/Menu.js index dadb6b8..deb481b 100644 --- a/accelerator-home-ui/src/views/Menu.js +++ b/accelerator-home-ui/src/views/Menu.js @@ -27,11 +27,11 @@ var route = { Router.navigate('menu') Router.focusPage() }, + // 1: () => { + // Router.navigate('epg') + // Router.focusPage() + // }, 1: () => { - Router.navigate('epg') - Router.focusPage() - }, - 2: () => { Router.navigate('appinfo') Router.focusPage() }, diff --git a/accelerator-home-ui/static/data/SidePanelInfo.js b/accelerator-home-ui/static/data/SidePanelInfo.js index 99f24e3..d39a43d 100644 --- a/accelerator-home-ui/static/data/SidePanelInfo.js +++ b/accelerator-home-ui/static/data/SidePanelInfo.js @@ -24,10 +24,10 @@ export var sidePanelInfo = [ title: 'Apps', url: '/images/sidePanel/menu.png', }, - { - title: 'EPG', - url: '/images/sidePanel/metro.png', - }, + // { + // title: 'EPG', + // url: '/images/sidePanel/metro.png', + // }, { title: 'AppInfo', url: '/images/sidePanel/settings.png', diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 6a7b48c..273a523 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.7", - "versionName": "6.0.7", + "version": "6.0.8", + "versionName": "6.0.8", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From 63623bc846a83f068b17fea2c4d3772f5e8e5491 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Mon, 20 Apr 2026 18:06:51 +0530 Subject: [PATCH 41/52] RDKEAPPRT-705 Changelog updates for 6.0.8 Signed-off-by: suryag23 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5e7c8f..902f03f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,20 @@ 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). +#### [6.0.8](https://github.com/rdkcentral/rdke-refui/compare/6.0.7...6.0.8) + +- RDKMVE-1860 Guide page is not loading and RDKEAPPRT-693 Wakesrc LAN is not set by default [`#186`](https://github.com/rdkcentral/rdke-refui/pull/186) +- Merge tag '6.0.7' into develop [`6d2d811`](https://github.com/rdkcentral/rdke-refui/commit/6d2d811f9ae4e1532816ba83a151bd309c56ad0a) + #### [6.0.7](https://github.com/rdkcentral/rdke-refui/compare/6.0.3...6.0.7) +> 17 April 2026 + - RDKEAPPRT-695 Incorrect IP address displayed on Network Info page after network reconnection and package version update for refui and wpe [`#183`](https://github.com/rdkcentral/rdke-refui/pull/183) - RDKEAPPRT-684 Sleep Timer and Screen-Saver is not working [`#182`](https://github.com/rdkcentral/rdke-refui/pull/182) - RDKEAPPRT-692 Handle Keycode 8 after Tatlow RCU pairing during FTI toavoid black screen and contain some fix for RCU pairing and powerstate [`#181`](https://github.com/rdkcentral/rdke-refui/pull/181) - RDKMVE-2127 From Ref UI Home screen, Pressing Volume +/- leads to UI blank in the display [`#180`](https://github.com/rdkcentral/rdke-refui/pull/180) +- RDKEAPPRT-705 Changelog updates for 6.0.7 [`4b1d5be`](https://github.com/rdkcentral/rdke-refui/commit/4b1d5bef54924bfa99e6a8a62003e155db98b7b4) - Merge tag '6.0.3' into develop [`c6030f2`](https://github.com/rdkcentral/rdke-refui/commit/c6030f2f54ffc42cd26e0e96688a41b460c13590) #### [6.0.3](https://github.com/rdkcentral/rdke-refui/compare/6.0.2...6.0.3) From 27a03b2410daf18461408d60112c27b6b4bd0e73 Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Wed, 29 Apr 2026 10:21:10 -0400 Subject: [PATCH 42/52] RDKEAPPRT-741: Upgrade the depends - wpe version --- bolt/package-configs/com.rdkcentral.refui.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 273a523..7d27e3c 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -6,7 +6,7 @@ "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", "dependencies": { - "com.rdkcentral.wpe": "0.3.0" + "com.rdkcentral.wpe": "0.3.1" }, "permissions": [ "urn:rdk:permission:home-app", From a8fdfebd0ec5e24d9507b1b13477ae966054e305 Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Wed, 29 Apr 2026 10:37:39 -0400 Subject: [PATCH 43/52] RDKEAPPRT-741 Changelog updates and refui version updates for 6.0.9 Signed-off-by: yashaswini-rk --- CHANGELOG.md | 8 ++++++++ accelerator-home-ui/settings.json | 2 +- bolt/package-configs/com.rdkcentral.refui.json | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 902f03f..12f0102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,17 @@ 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). +#### [6.0.9](https://github.com/rdkcentral/rdke-refui/compare/6.0.8...6.0.9) + +- RDKEAPPRT-741: Upgrade the depends - wpe version [`#190`](https://github.com/rdkcentral/rdke-refui/pull/190) +- Merge tag '6.0.8' into develop [`2a946cc`](https://github.com/rdkcentral/rdke-refui/commit/2a946ccca509b994c18e36b96017cf5cdeaaa9d5) + #### [6.0.8](https://github.com/rdkcentral/rdke-refui/compare/6.0.7...6.0.8) +> 20 April 2026 + - RDKMVE-1860 Guide page is not loading and RDKEAPPRT-693 Wakesrc LAN is not set by default [`#186`](https://github.com/rdkcentral/rdke-refui/pull/186) +- RDKEAPPRT-705 Changelog updates for 6.0.8 [`63623bc`](https://github.com/rdkcentral/rdke-refui/commit/63623bc846a83f068b17fea2c4d3772f5e8e5491) - Merge tag '6.0.7' into develop [`6d2d811`](https://github.com/rdkcentral/rdke-refui/commit/6d2d811f9ae4e1532816ba83a151bd309c56ad0a) #### [6.0.7](https://github.com/rdkcentral/rdke-refui/compare/6.0.3...6.0.7) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index e0b8e07..a15c2ed 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.8" + "version": "6.0.9" } } diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 7d27e3c..f2f1c9c 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.8", - "versionName": "6.0.8", + "version": "6.0.9", + "versionName": "6.0.9", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From 41ee0083c8b49f38194f6097479ab0e05623da8c Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Thu, 7 May 2026 10:26:45 +0530 Subject: [PATCH 44/52] RDKEAPPRT-713 Device enters Standby instead of Deep Sleep when EnergySaver is enabled in UI (#192) * RDKEAPPRT-713 Device enters Standby instead of Deep Sleep when Energy Saver is enabled in UI * Updated the log message --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 56 ++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index a15c2ed..26093c0 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.9" + "version": "6.0.10" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index cb52da9..10429e0 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -255,7 +255,14 @@ export default class App extends Router.App { _captureKey(key) { this.LOG("Got keycode : " + JSON.stringify(key.keyCode)) this.LOG("powerState ===>" + JSON.stringify(GLOBALS.powerState)) - if (GLOBALS.powerState !== PowerState.POWER_STATE_ON) { + if (GLOBALS.powerState === PowerState.POWER_STATE_DEEP_SLEEP || GLOBALS.powerState === PowerState.POWER_STATE_LIGHT_SLEEP) { + if (key.keyCode !== Keymap.Power) { + this.LOG("Ignoring non-power key press while device is in sleep state") + return true + } + this.initializeInactivityEngine(); + return this._performKeyPressOPerations(key) + } else if (GLOBALS.powerState !== PowerState.POWER_STATE_ON) { appApi.setPowerState(PowerState.POWER_STATE_ON).then(res => { res ? this.LOG("successfully set the power state to ON from " + JSON.stringify(GLOBALS.powerState)) : this.LOG("Failure while turning ON the device") GLOBALS.powerState = PowerState.POWER_STATE_ON; @@ -1779,20 +1786,31 @@ export default class App extends Router.App { this.currentStage = 'ScreenSaver'; await this.triggerScreensaver(); } - // Sleep Timer Stage - if (inactivityHelper.isValidTimeout(sleepTimer) && minutes === sleepTimer) { - this.LOG('Sleep Timer triggered'); + // Sleep Timer + Energy Saver combined logic + const hasSleepTimer = inactivityHelper.isValidTimeout(sleepTimer); + const hasEnergySaver = inactivityHelper.isValidTimeout(energySaver); + + if (hasSleepTimer && hasEnergySaver && minutes === sleepTimer) { + // Both enabled: at sleep timer time, execute energy saver (deep sleep) + this.LOG('Sleep Timer + Energy Saver triggered together — entering deep sleep'); + this.currentStage = 'EnergySaver'; + if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfclientAppName) { + this.LOG("Going to deep sleep due to inactivity (sleep timer + energy saver)"); + inactivityHelper._enterSleepMode(); + } + } else if (hasSleepTimer && !hasEnergySaver && minutes === sleepTimer) { + // Only sleep timer: standby as before + this.LOG('Sleep Timer triggered (no energy saver) — entering standby'); this.currentStage = 'SleepTimer'; if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfclientAppName) { inactivityHelper.standby('STANDBY'); } - } - // Energy Saver Stage - if (inactivityHelper.isValidTimeout(energySaver) && minutes === energySaver) { - this.LOG('Energy saver triggered'); + } else if (hasEnergySaver && !hasSleepTimer && minutes === energySaver) { + // Only energy saver (default 15 min): deep sleep + this.LOG('Energy Saver triggered (no sleep timer) — entering deep sleep'); this.currentStage = 'EnergySaver'; if (GLOBALS.powerState === "ON" && GLOBALS.topmostApp === GLOBALS.selfclientAppName) { - this.LOG("Going to sleep due to inactivity"); + this.LOG("Going to deep sleep due to inactivity (energy saver only)"); inactivityHelper._enterSleepMode(); } } @@ -2077,13 +2095,19 @@ export default class App extends Router.App { appApi.getPowerState().then(res => { this.LOG("getPowerState: " + JSON.stringify(res)); if (res.currentState === "ON") { - this.LOG("current powerState is ON so setting power state to LIGHT_SLEEP/DEEP_SLEEP depending of preferred option"); - appApi.setPowerState(res.previousState).then(result => { - if (result) { - this.LOG("successfully set powerstate to: " + JSON.stringify(res.previousState)) - return result - } - }) + const { energySaver } = inactivityHelper.getInactivityConfig(); + if (inactivityHelper.isValidTimeout(energySaver)) { + this.LOG("Energy Saver is enabled — going to DEEP_SLEEP on power key press"); + inactivityHelper._enterSleepMode(); + } else { + this.LOG("current powerState is ON so setting power state to LIGHT_SLEEP"); + appApi.setPowerState(PowerState.POWER_STATE_LIGHT_SLEEP).then(result => { + if (result) { + this.LOG("successfully set powerstate to LIGHT_SLEEP") + return result + } + }) + } } else { this.LOG("current powerState is " + JSON.stringify(res.currentState) + " so setting power state to ON"); appApi.setPowerState("ON").then(result => { From c1ae00a70d9aba9f8779cd44047be7a52daff90a Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Tue, 12 May 2026 10:32:38 +0530 Subject: [PATCH 45/52] RDKEAPPRT-875 Volume Overlay Missing and Volume Keys Unresponsive During Video Playback (#194) --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/App.js | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 26093c0..44b10f1 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.10" + "version": "6.0.11" } } diff --git a/accelerator-home-ui/src/App.js b/accelerator-home-ui/src/App.js index 10429e0..2dccb06 100644 --- a/accelerator-home-ui/src/App.js +++ b/accelerator-home-ui/src/App.js @@ -406,20 +406,23 @@ export default class App extends Router.App { this.tag("Volume").onVolumeMute(); } else { this.LOG("muting on some app") + this.tag("Volume").onVolumeMute(); } return true } else if (key.keyCode == Keymap.AudioVolumeUp && !Router.isNavigating()) { if (GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.tag("Volume").onVolumeKeyUp(); } else { - this.LOG("muting on some app") + this.LOG("increasing volume on some app") + this.tag("Volume").onVolumeKeyUp(); } return true } else if (key.keyCode == Keymap.AudioVolumeDown && !Router.isNavigating()) { if (GLOBALS.topmostApp === GLOBALS.selfclientAppName) { this.tag("Volume").onVolumeKeyDown(); } else { - this.LOG("muting on some app") + this.LOG("decreasing volume on some app") + this.tag("Volume").onVolumeKeyDown(); } return true } else { From 57178c7fb8e921d60d9399e0f77544e916685945 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Wed, 13 May 2026 18:37:12 +0530 Subject: [PATCH 46/52] 708,2245 -[RefUI] Not all UI texts are translated to Spanish (#195) * RDKEAPPRT-708 [RefUI] Not all UI texts are translated to Spanish * to address the review comments * Added extra fix to support spanish language in some more pages * Addressed the review comments --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/api/DACApi.js | 3 +- .../src/screens/AppCatalogLoginComponent.js | 34 +++++++++---------- accelerator-home-ui/src/views/AppInfoPage.js | 2 +- accelerator-home-ui/src/views/MainView.js | 4 +-- .../static/language/translations/es.json | 15 +++++++- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 44b10f1..a45e751 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.11" + "version": "6.0.12" } } diff --git a/accelerator-home-ui/src/api/DACApi.js b/accelerator-home-ui/src/api/DACApi.js index 79766e0..ab0a7d2 100644 --- a/accelerator-home-ui/src/api/DACApi.js +++ b/accelerator-home-ui/src/api/DACApi.js @@ -17,6 +17,7 @@ * limitations under the License. **/ +import { Language } from '@lightningjs/sdk'; import DownloadManager from './DownloadManagerApi'; import PackageManager from './PackageManagerApi'; import AppManager from './AppManagerApi'; @@ -130,7 +131,7 @@ async function downloadAndInstall(pkg, downloadedSize, totalSize, progress) { await DownloadManager.get().download(downloadURL, (downloadId, percent, failReason) => { if (!failReason) { if (percent !== 100) { - progress((downloadedSize + pkg.size * percent / 100) / totalSize, "Downloading"); + progress((downloadedSize + pkg.size * percent / 100) / totalSize, Language.translate("Downloading")); } else { resolve(downloadId); } diff --git a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index a6e1fa0..1c6c630 100644 --- a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -91,7 +91,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, Username: { x: 190, - y: 176, + y: 170, text: { text: Language.translate("Username") + ": ", fontFace: CONFIG.language.font, @@ -99,12 +99,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, }, UsernameBox: { - x: 400, + x: 425, y: 160, - texture: Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + texture: Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) }, UsernameText: { - x: 420, + x: 445, y: 170, zIndex: 2, text: { @@ -112,14 +112,14 @@ export default class AppCatalogLoginComponent extends Lightning.Component { fontSize: 25, fontFace: CONFIG.language.font, textColor: 0xffffffff, - wordWrapWidth: 1300, + wordWrapWidth: 1225, wordWrap: false, textOverflow: 'ellipsis', }, }, Password: { x: 190, - y: 246, + y: 240, text: { text: Language.translate("Password") + ":", fontFace: CONFIG.language.font, @@ -127,12 +127,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, }, PasswordBox: { - x: 400, + x: 425, y: 230, - texture: Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + texture: Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) }, Pwd: { - x: 420, + x: 445, y: 240, zIndex: 2, text: { @@ -140,7 +140,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { fontSize: 25, fontFace: CONFIG.language.font, textColor: 0xffffffff, - wordWrapWidth: 1300, + wordWrapWidth: 1225, wordWrap: false, textOverflow: 'ellipsis', }, @@ -171,7 +171,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, Keyboard: { y: 420, - x: 400, + x: 425, type: Keyboard, visible: false, zIndex: 2, @@ -229,7 +229,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { return [ class EnterUsername extends this { $enter() { - this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, CONFIG.theme.hex, false) } _handleDown() { this._setState("EnterPassword"); @@ -241,12 +241,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.tag("Keyboard").visible = true } $exit() { - this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + this.tag('UsernameBox').texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) } }, class EnterPassword extends this { $enter() { - this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, CONFIG.theme.hex, false) } _handleUp() { this._setState("EnterUsername"); @@ -264,12 +264,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.tag('Pwd').text.textColor = 0xffffffff } $exit() { - this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false); + this.tag('PasswordBox').texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false); } }, class PasswordSwitchState extends this { $enter() { - this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, CONFIG.theme.hex, false) + this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, CONFIG.theme.hex, false) this.tag('ShowPassword').text.textColor = CONFIG.theme.hex } _handleDown() { @@ -298,7 +298,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { } $exit() { - this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1273, 58, 0, 3, 0xffffffff, false) + this.tag("PasswordBox").texture = Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) this.tag('ShowPassword').text.textColor = 0xffffffff } }, diff --git a/accelerator-home-ui/src/views/AppInfoPage.js b/accelerator-home-ui/src/views/AppInfoPage.js index 50400d7..7ef5a6d 100644 --- a/accelerator-home-ui/src/views/AppInfoPage.js +++ b/accelerator-home-ui/src/views/AppInfoPage.js @@ -138,7 +138,7 @@ export default class AppInfoPage extends Lightning.Component { y: 30, mount: 0.5, text: { - text: 'OK', + text: Language.translate('OK'), fontSize: 32, fontFace: CONFIG.language.font, textColor: 0xFF000000 diff --git a/accelerator-home-ui/src/views/MainView.js b/accelerator-home-ui/src/views/MainView.js index 7f4393f..f73ebde 100644 --- a/accelerator-home-ui/src/views/MainView.js +++ b/accelerator-home-ui/src/views/MainView.js @@ -267,7 +267,7 @@ export default class MainView extends Lightning.Component { })) // Add "More Apps" item at the end apps.push({ - displayName: 'More Apps', + displayName: Language.translate('More Apps'), applicationType: 'MoreApps', uri: 'apps', url: '/images/sidePanel/moreapps.png', @@ -444,7 +444,7 @@ export default class MainView extends Lightning.Component { this._hideDacAppsLoader() // Clear stale cached apps (broken/default icons) and show only "More Apps" this.dacApps = [{ - displayName: 'More Apps', + displayName: Language.translate('More Apps'), applicationType: 'MoreApps', uri: 'apps', url: '/images/sidePanel/moreapps.png', diff --git a/accelerator-home-ui/static/language/translations/es.json b/accelerator-home-ui/static/language/translations/es.json index 49191c1..ad17c49 100644 --- a/accelerator-home-ui/static/language/translations/es.json +++ b/accelerator-home-ui/static/language/translations/es.json @@ -282,5 +282,18 @@ "TTS Endpoint":"Punto final TTS", "WiFi Status":"Estado WiFi", "Error Code :":"Código de error:", - "Error Msg :":"Mensaje de error:" + "Error Msg :":"Mensaje de error:", + "Recommended Apps":"Aplicaciones recomendadas", + "More Apps":"Más aplicaciones", + "Installed Apps":"Aplicaciones instaladas", + "Launch":"Iniciar", + "Uninstall":"Desinstalar", + "Update":"Actualizar", + "Connect to the Application Catalog":"Conectar al Catálogo de Aplicaciones", + "No Apps Installed":"No hay aplicaciones instaladas", + "Manage your installed applications":"Administre sus aplicaciones instaladas", + "Are you sure you want to uninstall this app?":"¿Está seguro de que desea desinstalar esta aplicación?", + "Press OK to enter Username":"Presione OK para ingresar el nombre de usuario", + "Username":"Nombre de usuario", + "Downloading":"Descargando" } From a18abb8d05fd0bc8245aad24313d3e3131de038a Mon Sep 17 00:00:00 2001 From: yashaswini-rk Date: Thu, 21 May 2026 15:32:06 -0400 Subject: [PATCH 47/52] RDKEAPPRT-783 Changelog updates for 6.0.12 Signed-off-by: yashaswini-rk --- bolt/package-configs/CHANGELOG.md | 348 ++++++++++++++++++ .../package-configs/com.rdkcentral.refui.json | 6 +- 2 files changed, 351 insertions(+), 3 deletions(-) create mode 100644 bolt/package-configs/CHANGELOG.md diff --git a/bolt/package-configs/CHANGELOG.md b/bolt/package-configs/CHANGELOG.md new file mode 100644 index 0000000..569d99a --- /dev/null +++ b/bolt/package-configs/CHANGELOG.md @@ -0,0 +1,348 @@ +### Changelog + +All notable changes to this project will be documented in this file. Dates are displayed in UTC. + +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). + +#### [6.0.12](https://github.com/rdkcentral/rdke-refui/compare/6.0.9...6.0.12) + +- 708,2245 -[RefUI] Not all UI texts are translated to Spanish [`#195`](https://github.com/rdkcentral/rdke-refui/pull/195) +- RDKEAPPRT-875 Volume Overlay Missing and Volume Keys Unresponsive During Video Playback [`#194`](https://github.com/rdkcentral/rdke-refui/pull/194) +- RDKEAPPRT-713 Device enters Standby instead of Deep Sleep when EnergySaver is enabled in UI [`#192`](https://github.com/rdkcentral/rdke-refui/pull/192) +- Merge tag '6.0.9' into develop [`6a31619`](https://github.com/rdkcentral/rdke-refui/commit/6a316192865b993a7b14d5e8921e9a06fe1522e4) + +#### [6.0.9](https://github.com/rdkcentral/rdke-refui/compare/6.0.8...6.0.9) + +> 29 April 2026 + +- RDKEAPPRT-741: Upgrade the depends - wpe version [`#190`](https://github.com/rdkcentral/rdke-refui/pull/190) +- RDKEAPPRT-741 Changelog updates and refui version updates for 6.0.9 [`a8fdfeb`](https://github.com/rdkcentral/rdke-refui/commit/a8fdfebd0ec5e24d9507b1b13477ae966054e305) +- Merge tag '6.0.8' into develop [`2a946cc`](https://github.com/rdkcentral/rdke-refui/commit/2a946ccca509b994c18e36b96017cf5cdeaaa9d5) + +#### [6.0.8](https://github.com/rdkcentral/rdke-refui/compare/6.0.7...6.0.8) + +> 20 April 2026 + +- RDKMVE-1860 Guide page is not loading and RDKEAPPRT-693 Wakesrc LAN is not set by default [`#186`](https://github.com/rdkcentral/rdke-refui/pull/186) +- RDKEAPPRT-705 Changelog updates for 6.0.8 [`63623bc`](https://github.com/rdkcentral/rdke-refui/commit/63623bc846a83f068b17fea2c4d3772f5e8e5491) +- Merge tag '6.0.7' into develop [`6d2d811`](https://github.com/rdkcentral/rdke-refui/commit/6d2d811f9ae4e1532816ba83a151bd309c56ad0a) + +#### [6.0.7](https://github.com/rdkcentral/rdke-refui/compare/6.0.3...6.0.7) + +> 17 April 2026 + +- RDKEAPPRT-695 Incorrect IP address displayed on Network Info page after network reconnection and package version update for refui and wpe [`#183`](https://github.com/rdkcentral/rdke-refui/pull/183) +- RDKEAPPRT-684 Sleep Timer and Screen-Saver is not working [`#182`](https://github.com/rdkcentral/rdke-refui/pull/182) +- RDKEAPPRT-692 Handle Keycode 8 after Tatlow RCU pairing during FTI toavoid black screen and contain some fix for RCU pairing and powerstate [`#181`](https://github.com/rdkcentral/rdke-refui/pull/181) +- RDKMVE-2127 From Ref UI Home screen, Pressing Volume +/- leads to UI blank in the display [`#180`](https://github.com/rdkcentral/rdke-refui/pull/180) +- RDKEAPPRT-705 Changelog updates for 6.0.7 [`4b1d5be`](https://github.com/rdkcentral/rdke-refui/commit/4b1d5bef54924bfa99e6a8a62003e155db98b7b4) +- Merge tag '6.0.3' into develop [`c6030f2`](https://github.com/rdkcentral/rdke-refui/commit/c6030f2f54ffc42cd26e0e96688a41b460c13590) + +#### [6.0.3](https://github.com/rdkcentral/rdke-refui/compare/6.0.2...6.0.3) + +> 7 April 2026 + +- Updated the version for refui boltpackage [`#175`](https://github.com/rdkcentral/rdke-refui/pull/175) +- RDKEAPPRT-688 Changelog updates for 6.0.3 [`a64ad51`](https://github.com/rdkcentral/rdke-refui/commit/a64ad5142fef9c1341028d211ade283bb8d58f5b) +- Merge tag '6.0.2' into develop [`7d4582c`](https://github.com/rdkcentral/rdke-refui/commit/7d4582c752991e63442df51fecbaf152e355e4c5) + +#### [6.0.2](https://github.com/rdkcentral/rdke-refui/compare/6.0.1...6.0.2) + +> 7 April 2026 + +- RDKEAPPRT-683: RemoteControl plugin API align with MW APIv3.4.2 [`#171`](https://github.com/rdkcentral/rdke-refui/pull/171) +- RDKEAPPRT-683: Fix the RCU pairing trigger timers [`47df636`](https://github.com/rdkcentral/rdke-refui/commit/47df6367819c67c9bcab0a5ed99fa3007e976d99) +- RDKEAPPRT-683: fix the RCU re scanning logic leak. [`2610642`](https://github.com/rdkcentral/rdke-refui/commit/2610642a37e0d975cfb59ac9d5d4aa498ae4a115) +- /RDKEAPPRT-683: stop the scan triggers after RCU pairing [`34ee6be`](https://github.com/rdkcentral/rdke-refui/commit/34ee6bea00a1aba71dcbc2e969ef5a6d22f2e94c) + +#### [6.0.1](https://github.com/rdkcentral/rdke-refui/compare/6.0.0...6.0.1) + +> 31 March 2026 + +- Feature/rdkeapprt 680 :Update to new RDK logos [`#168`](https://github.com/rdkcentral/rdke-refui/pull/168) +- RDKEAPPRT-682 Changelog and package config version updates for 6.0.1 [`32bbba6`](https://github.com/rdkcentral/rdke-refui/commit/32bbba6f7cde97607cac613f80240a174073c6bf) +- RDKEAPPRT-680 :Update new logo [`83513d8`](https://github.com/rdkcentral/rdke-refui/commit/83513d8d0566d994927583ed7891c655660af97f) +- RDKEAPPRT-680:Update the new logo files [`c2b261f`](https://github.com/rdkcentral/rdke-refui/commit/c2b261ff1ea9e4e72a8750f77652d6f4261775ce) + +### [6.0.0](https://github.com/rdkcentral/rdke-refui/compare/5.0.24...6.0.0) + +> 31 March 2026 + +- To refresh the App store and main view when the authentication done [`#166`](https://github.com/rdkcentral/rdke-refui/pull/166) +- RDKEAPPRT-661 Add support for new authorization in App Catalog [`#165`](https://github.com/rdkcentral/rdke-refui/pull/165) +- RDKEAPPRT-621,606,648,644 fix for Language screen and powerstate issue [`#164`](https://github.com/rdkcentral/rdke-refui/pull/164) +- RDKEAPPRT-646 Create the Username, Password page and add it inside the settings route [`#163`](https://github.com/rdkcentral/rdke-refui/pull/163) +- RDKEAPPRT-645 Add default error overlay when user tries to enter VOD content [`#162`](https://github.com/rdkcentral/rdke-refui/pull/162) +- RDKEAPPRT-612 :Add dac store details via RFC [`#160`](https://github.com/rdkcentral/rdke-refui/pull/160) +- RDKEAPPRT-626,627,628,605,608,622 Fix error and uninstall overlay screen with bug fixes [`#161`](https://github.com/rdkcentral/rdke-refui/pull/161) +- RDKEAPPRT-601,602 App side loading and App side loading and closeApp() function [`#158`](https://github.com/rdkcentral/rdke-refui/pull/158) +- To merge the changes from Feature/app managers to develop [`#157`](https://github.com/rdkcentral/rdke-refui/pull/157) +- RDKEAPPRT-576 Improve focus management [`#155`](https://github.com/rdkcentral/rdke-refui/pull/155) +- RDKEAPPRT-341 App managers intake: abstractions, API migration and YouTube Launch Support [`#146`](https://github.com/rdkcentral/rdke-refui/pull/146) +- RDKEAPPRT-571 Create UI prototype with My Apps, Recommended Apps, VOD Rows and Appinfo (#156) [`eff1a86`](https://github.com/rdkcentral/rdke-refui/commit/eff1a864e55c28ed1c542e26f818d20f082a6dca) +- RDKEAPPRT-538 Add basic integration with the RDK Reference DAC 2.0 App Store (#152) [`82eda3d`](https://github.com/rdkcentral/rdke-refui/commit/82eda3d7b34b80be63bdf3d0cb39d6c3f7f1f681) +- Changes for the error and uninstall overlay screen then some bug fixes also part of this [`749f89d`](https://github.com/rdkcentral/rdke-refui/commit/749f89d0af61e7aab7d96cb70a392e4efb8f8020) + +#### [5.0.24](https://github.com/rdkcentral/rdke-refui/compare/5.0.20...5.0.24) + +> 12 February 2026 + +- RDKEAPPRT-575 [RDKUI] 5.0.24 Merge latest changes from develop to main, create release tag, and publish release. [`#154`](https://github.com/rdkcentral/rdke-refui/pull/154) +- RDKEAPPRT-268 [RDK UI] Replace deprecated APIs for USB Media Device [`#153`](https://github.com/rdkcentral/rdke-refui/pull/153) +- RDKEAPPRT-394 Adopt to New APIs for deprecated ones if not yet [`#151`](https://github.com/rdkcentral/rdke-refui/pull/151) +- RDKEAPPRT-533-[RDK UI] Device is not discovered via DIAL after re-enabling Local Device Discovery option [`#150`](https://github.com/rdkcentral/rdke-refui/pull/150) +- RDKEAPPRT-518 All SSIDs are not visible in FTI SSID selection screen [`#149`](https://github.com/rdkcentral/rdke-refui/pull/149) +- RDKEAPPRT-575 Changelog updates for 5.0.24 [`59d8252`](https://github.com/rdkcentral/rdke-refui/commit/59d8252ac9401f7882716fc5c055346653004996) +- Merge tag '5.0.20' into develop [`4413c1c`](https://github.com/rdkcentral/rdke-refui/commit/4413c1cf7d14b54c8952299b291a44f311d7033e) + +#### [5.0.20](https://github.com/rdkcentral/rdke-refui/compare/5.0.17...5.0.20) + +> 18 December 2025 + +- [RDKUI] 5.0.20 Merge latest changes from develop to main, create release tag, and publish release. [`#147`](https://github.com/rdkcentral/rdke-refui/pull/147) +- RDKEAPPRT-420: Unable to change Sleep timer and energy saver [`#143`](https://github.com/rdkcentral/rdke-refui/pull/143) +- RDKEAPPRT-344- Migrate the New powermanger plugin APIs in UI [`#142`](https://github.com/rdkcentral/rdke-refui/pull/142) +- RDKEAPPRT-358: Once disabled, not able to toggle Local Device Discovery radio to ON state [`#141`](https://github.com/rdkcentral/rdke-refui/pull/141) +- RDKEAPPRT-356 Incorrect behaviors seen after giving wrong credentials for WiFi SSID Or changing the password for a connected SSID [`#140`](https://github.com/rdkcentral/rdke-refui/pull/140) +- [RDKEAPPRT-328] - Use UserSettings instead of UserPreferences for storing currently set UI language [`#139`](https://github.com/rdkcentral/rdke-refui/pull/139) +- RDKEAPPRT-340: Ethernet interface stuck on “Configuring as default” with continuous loader [`#138`](https://github.com/rdkcentral/rdke-refui/pull/138) +- RDKEAPPRT-241 Remove Features Dependent on Deprecated System Plugin APIs and introduced Power manager APIs [`#137`](https://github.com/rdkcentral/rdke-refui/pull/137) +- RDKEAPPRT-262: [RDK UI] Sleep timer value is not reflected in UI [`#136`](https://github.com/rdkcentral/rdke-refui/pull/136) +- RDKEAPPRT-241 Remove Features Dependent on Deprecated System Plugin APIs [`c07106e`](https://github.com/rdkcentral/rdke-refui/commit/c07106edb648a0a7959bb8c4096f6b72041581ac) +- addressed the review comments [`27819d5`](https://github.com/rdkcentral/rdke-refui/commit/27819d567b4692be6ac2bc978fad7c68874d05c9) +- Addressed the review comments [`d0c5c60`](https://github.com/rdkcentral/rdke-refui/commit/d0c5c6055dd988c50bab309eee8b9906a1091617) + +#### [5.0.17](https://github.com/rdkcentral/rdke-refui/compare/5.0.12...5.0.17) + +> 30 October 2025 + +- RDKEAPPRT-356 Incorrect behaviors seen after giving wrong credentials for WiFi SSID Or changing the password for a connected SSID [`#140`](https://github.com/rdkcentral/rdke-refui/pull/140) +- RDKEAPPRT-377 Changelog updates for 5.0.17 [`c4087fe`](https://github.com/rdkcentral/rdke-refui/commit/c4087fe3a6c759fa4e1c5bad8675718346e2642d) + +#### [5.0.12](https://github.com/rdkcentral/rdke-refui/compare/5.0.9...5.0.12) + +> 17 October 2025 + +- RDKEAPPRT-331 [RDKUI] 5.0.12 Merge latest changes from develop to main, create release tag, and publish release. [`#135`](https://github.com/rdkcentral/rdke-refui/pull/135) +- RDKEAPPRT-319 [Netflix7] Verify and fix DIAL config for Netflix,Amazon [`#134`](https://github.com/rdkcentral/rdke-refui/pull/134) +- RDKEAPPRT-139 [RDK UI] DAC APPS Section UI Freeze - No Apps List & Remote Unresponsive, Requires Device Restart [`#133`](https://github.com/rdkcentral/rdke-refui/pull/133) +- RDKEAPPRT-298 Fix DIAL CORS setup for YouTube apps [`#132`](https://github.com/rdkcentral/rdke-refui/pull/132) +- RDKEAPPRT-319 [Netflix7] Verify and fix DIAL config for Netflix [`c6d7e7d`](https://github.com/rdkcentral/rdke-refui/commit/c6d7e7d8e55ee466165fba5aec5de7d5e99fc73c) +- RDKEAPPRT-331 Changelog updates for 5.0.12 [`fe0a0bc`](https://github.com/rdkcentral/rdke-refui/commit/fe0a0bc05f3957581c7d74c11cb73a4853d93360) +- RDKEAPPRT-298 [YT25][YTS] Several YouTube DIAL Protocol tests failed [`20f5e0f`](https://github.com/rdkcentral/rdke-refui/commit/20f5e0f65fb2234c826cd816158cfd0664f40ffe) + +#### [5.0.9](https://github.com/rdkcentral/rdke-refui/compare/5.0.7...5.0.9) + +> 9 October 2025 + +- RDKEAPPRT-315 [RDKUI] 5.0.9 Merge latest changes from develop to main, create release tag, and publish release. [`#131`](https://github.com/rdkcentral/rdke-refui/pull/131) +- RDKEAPPRT-312 [Netflix7][RTK] App state not reported to DIAL and Hide/stop fails [`#130`](https://github.com/rdkcentral/rdke-refui/pull/130) +- RDKEAPPRT-266-[YT25] Handle Netflix, YouTube and Prime Video buttons [`#129`](https://github.com/rdkcentral/rdke-refui/pull/129) +- RDKEAPPRT-315 Changelog updates for 5.0.9 [`d55c528`](https://github.com/rdkcentral/rdke-refui/commit/d55c528e0d2d7d64ecbcf7796f4e1ea1690bc17a) +- RDKEAPPRT-312 [Netflix7][RTK] App state not reported to DIAL and Hide/stop [`05c29e7`](https://github.com/rdkcentral/rdke-refui/commit/05c29e779631c6448cdfb022ccf30b3d366cfa2a) +- Merge tag '5.0.7' into develop [`21fa916`](https://github.com/rdkcentral/rdke-refui/commit/21fa916e0327babade062657691f38f6103f1b42) + +#### [5.0.7](https://github.com/rdkcentral/rdke-refui/compare/5.0.1...5.0.7) + +> 6 October 2025 + +- RDKEAPPRT-275 [RDKUI] 5.0.7 Merge latest changes from develop to main, create release tag, and publish release. [`#127`](https://github.com/rdkcentral/rdke-refui/pull/127) +- RDKEAPPRT-251 FTI Page – Ethernet Option Shows ‘Not Connected’ Error Despite Active Connection [`#126`](https://github.com/rdkcentral/rdke-refui/pull/126) +- RDKEAPPRT-221 [RDK UI] ResidentApp plugin crashes when try to start playback of some Featured Video on Demand assets00~[RDK UI] ResidentApp plugin crashes when try to start playback of some Featured Video on Demand assets [`#124`](https://github.com/rdkcentral/rdke-refui/pull/124) +- Deploy cla action [`#125`](https://github.com/rdkcentral/rdke-refui/pull/125) +- RDKEAPPRT-236 : Activate LISA plugin from residentapp.service [`#123`](https://github.com/rdkcentral/rdke-refui/pull/123) +- RDKEAPPRT-230-[RDK UI] [DIAL] Update Netflix name field in application params [`#122`](https://github.com/rdkcentral/rdke-refui/pull/122) +- RDKEAPPRT-225,226 [RDK UI][Miracast] Pressing any RCU button except OK on miracast connection acceptance screen deny connection,[RDK UI][Miracast] It is not possible to reconnect mobile device using miracast and fixed Minor dial fix [`#121`](https://github.com/rdkcentral/rdke-refui/pull/121) +- RDKEAPPRT-209,208 [REFUI][DIAL] Adopt to the XCast plugin's deeplink payload change,[REFUI][DIAL] The XCAST initializaion flow is incorrect [`#120`](https://github.com/rdkcentral/rdke-refui/pull/120) +- Updated the APP.js Ident [`6f2c44b`](https://github.com/rdkcentral/rdke-refui/commit/6f2c44b6f427b58ec124b2ed1186c1c4a6955816) +- Final Dial fix [`c2f6984`](https://github.com/rdkcentral/rdke-refui/commit/c2f6984e3bff937c07f41ad90f7cd01d59f81113) +- RDKEAPPRT-221 [RDK UI] ResidentApp plugin crashes when try to [`301ed96`](https://github.com/rdkcentral/rdke-refui/commit/301ed9655172434008d8f3fe59681b808b6062ab) + +### [5.0.1](https://github.com/rdkcentral/rdke-refui/compare/4.7.19...5.0.1) + +> 10 September 2025 + +- RDKEAPPRT-189 [RDKE] Prepare Release Refui 5.0.1 [`#119`](https://github.com/rdkcentral/rdke-refui/pull/119) +- RDKUI-114 [RDK UI] Replace legacy network APIs with networkmanager APIs [`#118`](https://github.com/rdkcentral/rdke-refui/pull/118) +- RDKUI -848 unable to debug refui, many console message in source code do not result in actual log line on journalctl [`#116`](https://github.com/rdkcentral/rdke-refui/pull/116) +- RDKUI-862,865 Clear Cookies and App Data option Failed to Remove App Data and Logins,In overlay unable to see the slider in clear cookies and app data row [`#115`](https://github.com/rdkcentral/rdke-refui/pull/115) +- RDKUI -744 [BCM][Rpi][AML][RTK]Unable to unmute the device after increasing the volume [`#114`](https://github.com/rdkcentral/rdke-refui/pull/114) +- RDKUI - 861 No proper error message shown for wrong WiFi password at FTI page [`#113`](https://github.com/rdkcentral/rdke-refui/pull/113) +- RDKUI-856, RDKUI-855: WiFi Error message to match current Language, adjust the TEXT overlap. [`#112`](https://github.com/rdkcentral/rdke-refui/pull/112) +- RDKUI-859 Title in Settings / Other Settings / Advanced Settings / TTS is not proper. Also text is not changed to Spanish [`#111`](https://github.com/rdkcentral/rdke-refui/pull/111) +- RDKUI -857 When switching from one ssid to another from CONNECION_LOST error message is seen [`#110`](https://github.com/rdkcentral/rdke-refui/pull/110) +- RDKUI-860: adopt devicetype ontology change - IpTv [`#109`](https://github.com/rdkcentral/rdke-refui/pull/109) +- Deploy cla action [`#104`](https://github.com/rdkcentral/rdke-refui/pull/104) +- RDKUI-854 Modify UI logic for Netflix URL Formation [`#108`](https://github.com/rdkcentral/rdke-refui/pull/108) +- RDKUI-838 [RDKE] After launching the app from UI, initial key press is not working [`#107`](https://github.com/rdkcentral/rdke-refui/pull/107) +- changes added for all screen and apis [`6a5e716`](https://github.com/rdkcentral/rdke-refui/commit/6a5e71680ee9b768d5988d211500ca205297aad4) +- Added console abstraction for Api folder and some of the screens [`b970307`](https://github.com/rdkcentral/rdke-refui/commit/b970307d12ae4c93e97cd5fe6f80a25ce1451236) +- Networkmanager APIs migrated to these pages [`c5389d5`](https://github.com/rdkcentral/rdke-refui/commit/c5389d5bdc85aba679cd540d617f4390f7822e03) + +#### [4.7.19](https://github.com/rdkcentral/rdke-refui/compare/4.7.18...4.7.19) + +> 25 June 2025 + +- RDKUI-853 [RDKE] Prepare Release Refui 4.7.19 [`#106`](https://github.com/rdkcentral/rdke-refui/pull/106) +- RDKUI-852: Correctly set language during FTI [`#105`](https://github.com/rdkcentral/rdke-refui/pull/105) +- RDKUI-853 Changelog updates for 4.7.19 [`6893995`](https://github.com/rdkcentral/rdke-refui/commit/68939952bd7dd06ea6f98a89e30d29da2c88a6ce) +- Merge tag '4.7.18' into develop [`9eec0fd`](https://github.com/rdkcentral/rdke-refui/commit/9eec0fdb9bf6ddeabc9034bc6b99050b0dd9e704) + +#### [4.7.18](https://github.com/rdkcentral/rdke-refui/compare/4.7.15...4.7.18) + +> 24 June 2025 + +- RDKUI -850 [RDKE] Prepare Release Refui 4.7.18 [`#103`](https://github.com/rdkcentral/rdke-refui/pull/103) +- FTI: Update UI langauge and localstorage with default selected value [`#102`](https://github.com/rdkcentral/rdke-refui/pull/102) +- RDKUI- 847 [RDKE][DAC] YouTube 2025 (RPI4) DAC App is not listed in the App Catalog Page [`#101`](https://github.com/rdkcentral/rdke-refui/pull/101) +- RDKUI-849: [RDKE][AVPK] Remove Amazon hibernation on HDMI plugin disconnection/change [`#100`](https://github.com/rdkcentral/rdke-refui/pull/100) +- RDKUI- 847 [RDKE][DAC] YouTube 2025 (RPI4) DAC App is not listed in the App Catalog [`b59090f`](https://github.com/rdkcentral/rdke-refui/commit/b59090f6f5e1697635cfdde81251184933c1b08b) +- RDKUI-850 Changelog updates for 4.7.18 [`da54e6c`](https://github.com/rdkcentral/rdke-refui/commit/da54e6c0532022ab347a07275dbd845e0a1c9faf) +- Update version [`b246c8a`](https://github.com/rdkcentral/rdke-refui/commit/b246c8a7242c780b229db57b46ff7f6d1ab4eceb) + +#### [4.7.15](https://github.com/rdkcentral/rdke-refui/compare/4.7.9...4.7.15) + +> 13 June 2025 + +- RDKUI-845 [RDKE] Prepare Release Refui 4.7.15 [`#97`](https://github.com/rdkcentral/rdke-refui/pull/97) +- RDKUI 844 [AVPPK] Incorrect app name in the appBundle.js and fix for FTI Wifi, language issue [`#96`](https://github.com/rdkcentral/rdke-refui/pull/96) +- RDKUI-806 [RDKE] FTI disappears after few seconds without any user interaction [`#95`](https://github.com/rdkcentral/rdke-refui/pull/95) +- RDKUI 822-[RDKE][YT25] Add handling of DAB KEY_EXIT event [`#94`](https://github.com/rdkcentral/rdke-refui/pull/94) +- RDKUI-829: add the missing WiFi error code [`#91`](https://github.com/rdkcentral/rdke-refui/pull/91) +- RDKUI-835: Create TTS Screen to toggle TTS support and input endpoint URL [`#86`](https://github.com/rdkcentral/rdke-refui/pull/86) +- RDKUI 833-Align UI with XCast naming update for Netflix [`#85`](https://github.com/rdkcentral/rdke-refui/pull/85) +- RDKUI-837 [RPI][AL] setVisibility API params from UI is wrong when triggered from 'onApplicationLaunched' event [`#84`](https://github.com/rdkcentral/rdke-refui/pull/84) +- Basic TTS screen and switch working. Started work on adding UserSettings API [`0680b3f`](https://github.com/rdkcentral/rdke-refui/commit/0680b3fb596fde3bb948f23a3805862427f238a9) +- Enable option to enter TTS endpoint from the UI [`c5fe5c1`](https://github.com/rdkcentral/rdke-refui/commit/c5fe5c1995a5adbbc744629ddeeee96c21d49e1a) +- RDKUI 806 -Refactored the storage.get logic for setup and [`bec2d73`](https://github.com/rdkcentral/rdke-refui/commit/bec2d731aaff3c2757ce107472a08cce605e023b) + +#### [4.7.9](https://github.com/rdkcentral/rdke-refui/compare/4.7.5...4.7.9) + +> 28 May 2025 + +- RDKUI-834 [RDKE] Prepare Release Refui 4.7.9 [`#83`](https://github.com/rdkcentral/rdke-refui/pull/83) +- RDKUI-832 [RDKE][YT25] Do not enter deep sleep when Fast Forward key is pressed [`#82`](https://github.com/rdkcentral/rdke-refui/pull/82) +- PREMIUMAPP-3286: Autostart TTS plugin [`#81`](https://github.com/rdkcentral/rdke-refui/pull/81) +- RDKUI-831 Unable to see the DAC apps by adding the configure URL in LISA.json [`#79`](https://github.com/rdkcentral/rdke-refui/pull/79) +- RDKUI-829 Getting Unexpected ErrorCode from the onError event from WIFI plugin [`#78`](https://github.com/rdkcentral/rdke-refui/pull/78) +- RDKUI-826 Miracast message language is not changed to Spanish [`#77`](https://github.com/rdkcentral/rdke-refui/pull/77) +- RDKUI-834 Changelog updates for 4.7.9 [`0c6397d`](https://github.com/rdkcentral/rdke-refui/commit/0c6397dd1b72a9b99076ab376008838d801937b1) +- Merge tag '4.7.5' into develop [`7b47d8d`](https://github.com/rdkcentral/rdke-refui/commit/7b47d8dd4f90e719909f456a70bf51cde3e9b9a8) + +#### [4.7.5](https://github.com/rdkcentral/rdke-refui/compare/4.7.1...4.7.5) + +> 14 May 2025 + +- RDKUI-828 [RDKE] Prepare Release Refui 4.7.5 [`#74`](https://github.com/rdkcentral/rdke-refui/pull/74) +- RDKUI-827 After installing DAC bundle, cobalt is still not displayed in UI and added functionality under ApplicationTerminated,ApplicationResumed,ApplicationLaunched [`#73`](https://github.com/rdkcentral/rdke-refui/pull/73) +- RDKUI 816-[RDKE] Remove deprecated plugin dependency [`#72`](https://github.com/rdkcentral/rdke-refui/pull/72) +- RDKUI-819 RDK UI Side Pane icon : Selectio indicator pointing to Incorrect UI Item [`#71`](https://github.com/rdkcentral/rdke-refui/pull/71) +- RDKUI-821 Unable to see the connected remote Details in the Vocie Remote Control Page [`#70`](https://github.com/rdkcentral/rdke-refui/pull/70) +- RDKUI-828: Changelog updates for 4.7.5 [`a17cb5a`](https://github.com/rdkcentral/rdke-refui/commit/a17cb5acad7be3b907f518bdd611826b48b87a83) +- To update the Line number in the template [`5c69324`](https://github.com/rdkcentral/rdke-refui/commit/5c693240b79f3b0d32b021d7be26ee03188b8635) +- Removed duplicate console warn [`68fd55c`](https://github.com/rdkcentral/rdke-refui/commit/68fd55cfbe0615fba3a24e83870961d549f1a66f) + +#### [4.7.1](https://github.com/rdkcentral/rdke-refui/compare/4.7.0...4.7.1) + +> 30 April 2025 + +- RefUI release 4.7.1 [`#67`](https://github.com/rdkcentral/rdke-refui/pull/67) +- RDKUI-820 [RDKE] [XCAST] Need to change the URL formation logic for Xcast [`#66`](https://github.com/rdkcentral/rdke-refui/pull/66) +- RDKUI-825: Changelog updates for 4.7.1 [`7e2b200`](https://github.com/rdkcentral/rdke-refui/commit/7e2b200a489ee3a7d8ad186a152d2322aafcb129) +- Merge tag '4.7.0' into develop [`d74d65d`](https://github.com/rdkcentral/rdke-refui/commit/d74d65de8f82c8e320100c07c5334766a8d720f4) + +#### [4.7.0](https://github.com/rdkcentral/rdke-refui/compare/4.6.6...4.7.0) + +> 25 April 2025 + +- RDKUI-817: update documentation userfriendly [`#63`](https://github.com/rdkcentral/rdke-refui/pull/63) +- RDKUI-817: update documentation userfriendly [`#62`](https://github.com/rdkcentral/rdke-refui/pull/62) +- RDKUI-817: refui v4.7.0 release [`#60`](https://github.com/rdkcentral/rdke-refui/pull/60) +- RDKUI-807 [RDKE] Analyze the impact of the unavailability of the "LocationSync" plugin [`#59`](https://github.com/rdkcentral/rdke-refui/pull/59) +- PREMIUMAPP-3280 Fix YouTube state synchronization in DIAL [`#58`](https://github.com/rdkcentral/rdke-refui/pull/58) +- 814-[RDKE][YT25] Enable network standby mode [`#57`](https://github.com/rdkcentral/rdke-refui/pull/57) +- RDKUI-805 [RDKE] Use result.status.netTypeSupported response payload in org.rdk.RemoteControl.startPairing instead of hardcoded value [`#56`](https://github.com/rdkcentral/rdke-refui/pull/56) +- RKUI-803 Wifi error is popping up even though ethernet is connected and set as the default interface [`#55`](https://github.com/rdkcentral/rdke-refui/pull/55) +- PREMIUMAPP-3220 [AMLS905X4-2040] : [RDKE][YT25] OCDM plugin is not activated in RDKE builds [`#54`](https://github.com/rdkcentral/rdke-refui/pull/54) +- RDKUI-798 Only 15 SSIDs are visible in the Wifi screen of User On boarding [`#53`](https://github.com/rdkcentral/rdke-refui/pull/53) +- [RDKE] Use result.status.netTypeSupported response payload in org.rdk.RemoteControl.startPairing instead of hardcoded value [`513bf49`](https://github.com/rdkcentral/rdke-refui/commit/513bf493841602da374a1e11cfcf9d503f737d54) +- RDKUI-817: Changelog updates for 4.7.0 [`7206146`](https://github.com/rdkcentral/rdke-refui/commit/720614690f09b2734b83fe28a9249f4d607108b5) +- Addressed Review comments [`5b45c77`](https://github.com/rdkcentral/rdke-refui/commit/5b45c77e6bbc0d10d898925ec8c3fc3e42e2a85b) + +#### [4.6.6](https://github.com/rdkcentral/rdke-refui/compare/4.6.5...4.6.6) + +> 7 April 2025 + +- To release UI version 4.6.6 [`#50`](https://github.com/rdkcentral/rdke-refui/pull/50) +- AMLS905X4-2052 : [RDKE][YT25] PlayerInfo and DisplayInfo plugin is not activated in RDKE builds [`#47`](https://github.com/rdkcentral/rdke-refui/pull/47) +- [RDKE][DIAL] Need to invoke addkeyintercepts api while launching YT and removekeyintercept on closing [`#48`](https://github.com/rdkcentral/rdke-refui/pull/48) +- RDKUI-799: refui v4.6.6 release [`831296b`](https://github.com/rdkcentral/rdke-refui/commit/831296bb46b2fed4dda722dd26ef6e80936533d5) +- 797-[RDKE][DIAL] Need to invoke addkeyintercepts api while launching YT and removekeyintercept on closing [`0bdc070`](https://github.com/rdkcentral/rdke-refui/commit/0bdc070e27ecdda0f94a942e6a98ccc66841fc76) +- RDKUI-797: do not invoke RDKShellApis.removeKeyIntercept on onApplicationDisconnected [`364a19a`](https://github.com/rdkcentral/rdke-refui/commit/364a19a065fe6ef964f0593f4b2bd6a1636cb008) + +#### [4.6.5](https://github.com/rdkcentral/rdke-refui/compare/4.6.2...4.6.5) + +> 18 March 2025 + +- RDKEMW-1766, RDKUI-789, RDKUI-784, RDKUI-785, RDKUI-786: UI v4.6.5 to main [`#42`](https://github.com/rdkcentral/rdke-refui/pull/42) +- RDKUI-793 [`#41`](https://github.com/rdkcentral/rdke-refui/pull/41) +- RDKUI-789 [`#40`](https://github.com/rdkcentral/rdke-refui/pull/40) +- 784,785,786 [`#38`](https://github.com/rdkcentral/rdke-refui/pull/38) +- RDKEMW-1766: add power related systemd service dependencies [`#36`](https://github.com/rdkcentral/rdke-refui/pull/36) +- 784-UI Issues in Join other network page [`2b8c667`](https://github.com/rdkcentral/rdke-refui/commit/2b8c6675f5f96dc2b3469de955529f947f5082f5) + +#### [4.6.2](https://github.com/rdkcentral/rdke-refui/compare/4.6.1...4.6.2) + +> 28 February 2025 + +- Intake UI focus lont fix and build time optimization [`#35`](https://github.com/rdkcentral/rdke-refui/pull/35) +- Update residentApp.sh to remove bash dependency [`#34`](https://github.com/rdkcentral/rdke-refui/pull/34) +- 769-Focus issues observed in RDK UI [`#33`](https://github.com/rdkcentral/rdke-refui/pull/33) + +#### [4.6.1](https://github.com/rdkcentral/rdke-refui/compare/4.6.0...4.6.1) + +> 13 February 2025 + +- RDKUI-766: Enable miracast support and optimize BT scan triggers [`#32`](https://github.com/rdkcentral/rdke-refui/pull/32) +- 776-Remove voice remote pairing from background and fix for the language screen [`#31`](https://github.com/rdkcentral/rdke-refui/pull/31) +- To Bringback the miracast changes [`#30`](https://github.com/rdkcentral/rdke-refui/pull/30) +- 776-Remove voice remote pairing from background and fix for the [`702628a`](https://github.com/rdkcentral/rdke-refui/commit/702628ae2e45134458773f49298e4972a2706892) + +#### [4.6.0](https://github.com/rdkcentral/rdke-refui/compare/4.5.7...4.6.0) + +> 5 February 2025 + +- RDKUI-774: UIv 4.6.0 to main and MaintenanceMgr activation support [`#27`](https://github.com/rdkcentral/rdke-refui/pull/27) +- Version Updated to 4.6.0 [`#29`](https://github.com/rdkcentral/rdke-refui/pull/29) +- To Revert Miracast related changes [`#28`](https://github.com/rdkcentral/rdke-refui/pull/28) +- 774-To Update URL links for Feature Video on demand row [`#25`](https://github.com/rdkcentral/rdke-refui/pull/25) +- RDKVREFPLT-4612: activate MaintenanceManager plugin [`#26`](https://github.com/rdkcentral/rdke-refui/pull/26) +- 771,772-Design and integrate notification screen for events and the player functionality [`#24`](https://github.com/rdkcentral/rdke-refui/pull/24) +- RDKUI-770: class abstraction of Miracast related plugins [`#23`](https://github.com/rdkcentral/rdke-refui/pull/23) +- Navigator UI base code v4.5.7 [`#7`](https://github.com/rdkcentral/rdke-refui/pull/7) +- 768-Alexa related implementation fine-tuning to reduce API failures [`#22`](https://github.com/rdkcentral/rdke-refui/pull/22) +- adding package-lock.json [`a14b2b9`](https://github.com/rdkcentral/rdke-refui/commit/a14b2b9cee850564ac2cfb1991eb80939a576c6c) +- Revert "Merge pull request #23 from rdkcentral/Miracast" [`1401f4d`](https://github.com/rdkcentral/rdke-refui/commit/1401f4dfd979a7169bb6a934574cfc3c6fa043c5) +- 766- As part of this ticket abstracted the API and Event Listners for [`e89e41a`](https://github.com/rdkcentral/rdke-refui/commit/e89e41a881e488f69beac1d761a8a21ab8feebb3) + +#### 4.5.7 + +> 13 January 2025 + +- RDKUI-753: Remove the dist bundle [`#20`](https://github.com/rdkcentral/rdke-refui/pull/20) +- REFPLTV-2593: Activate ocicontainer plugin for DAC apps [`#18`](https://github.com/rdkcentral/rdke-refui/pull/18) +- RDKUI-759: isolating functionality from UI [`#17`](https://github.com/rdkcentral/rdke-refui/pull/17) +- Feature/rdkvrefplt 4241 refui refactoring [`#16`](https://github.com/rdkcentral/rdke-refui/pull/16) +- 761-YouTube App lifecycle handling based on HDMI source input change … [`#15`](https://github.com/rdkcentral/rdke-refui/pull/15) +- RDKUI-739: change device powerstate to laskknown or ON [`#12`](https://github.com/rdkcentral/rdke-refui/pull/12) +- 749,748-[DAC Apps]Simultaneous downloads of apps didn't happen from UI and Same SSID is listed multiple times in the UI [`#10`](https://github.com/rdkcentral/rdke-refui/pull/10) +- RDKUI-758 : UI stuck at RDK logo for platforms built without bluetooth [`#9`](https://github.com/rdkcentral/rdke-refui/pull/9) +- Addressed RDKUI-750,746 [`#8`](https://github.com/rdkcentral/rdke-refui/pull/8) +- RDKUI-747 : Deactivate/DIAL stop app after a DIAL Hide [`#6`](https://github.com/rdkcentral/rdke-refui/pull/6) +- RDKUI-755: update ReadMe with App Status [`#4`](https://github.com/rdkcentral/rdke-refui/pull/4) +- Update README.md [`#2`](https://github.com/rdkcentral/rdke-refui/pull/2) +- RDKUI-755: add COPYING support [`#3`](https://github.com/rdkcentral/rdke-refui/pull/3) +- Integrating the source code of opensource/RDK_apps into RDKE-refui repo [`#1`](https://github.com/rdkcentral/rdke-refui/pull/1) +- Remove the dist bundle [`4f4b829`](https://github.com/rdkcentral/rdke-refui/commit/4f4b829052450b9cde89f028682c474f6d7607ae) +- RDKVREFPLT-4378: add ermgr.service dependency for UI [`214f26b`](https://github.com/rdkcentral/rdke-refui/commit/214f26ba7a9f42aa2ad8a9b85cc0ac97369348cb) +- Removing the unwanted folders [`4ac1fc4`](https://github.com/rdkcentral/rdke-refui/commit/4ac1fc4ce91acfde8e09062f7b02fb3891cfd501) diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index f2f1c9c..c64ed36 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,12 +1,12 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.9", - "versionName": "6.0.9", + "version": "6.0.12", + "versionName": "6.0.12", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", "dependencies": { - "com.rdkcentral.wpe": "0.3.1" + "com.rdkcentral.wpe": "~0.3.1" }, "permissions": [ "urn:rdk:permission:home-app", From 6bcfc05f153be73e32bfc28ffadbe2836fdf943c Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Fri, 5 Jun 2026 16:55:37 +0530 Subject: [PATCH 48/52] RDKEAPPRT 751 -Enhance Authentication Feedback UI for App Catalogue (Success & Failure States) (#198) * RDKEAPPRT-751: Add catalog URL display and improve app catalog login experience - Validate login responses and add server URL export - Display catalog URL in login component UI - Add Connect button with dynamic color validation - Implement loading spinner during authentication - Add error handling popups for authentication failures Please refer ticket for more detials * Rebased the 751 changes * RDKEAPPRT-751: Include local changes for app catalog login and translations * addressed the review comments * addressed the review comments * Addressed the review comments * Addressed the review comments --------- Co-authored-by: Vaisakh Anand --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/api/AppCatalog.js | 4 + .../src/screens/AppCatalogLoginComponent.js | 376 ++++++++++++++++-- .../static/language/translations/en.json | 14 +- .../static/language/translations/es.json | 11 +- .../package-configs/com.rdkcentral.refui.json | 4 +- 6 files changed, 371 insertions(+), 40 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index a45e751..5ee2e54 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.12" + "version": "6.0.13" } } diff --git a/accelerator-home-ui/src/api/AppCatalog.js b/accelerator-home-ui/src/api/AppCatalog.js index 0a65a5d..859c557 100644 --- a/accelerator-home-ui/src/api/AppCatalog.js +++ b/accelerator-home-ui/src/api/AppCatalog.js @@ -447,3 +447,7 @@ export async function makeDownloadURL(url) { const handler = appCatalogHandler; return callAndHandleAuthExpired(handler, () => handler.makeDownloadURL(url)); } + +export async function getCatalogServerURL() { + return getServerURL(); +} diff --git a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js index 1c6c630..98a991b 100644 --- a/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js +++ b/accelerator-home-ui/src/screens/AppCatalogLoginComponent.js @@ -16,12 +16,12 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -import { Language, Lightning, Router } from '@lightningjs/sdk' +import { Language, Lightning, Router, Utils } from '@lightningjs/sdk' import { CONFIG } from '../Config/Config'; import { Keyboard } from '../ui-components/index' import { KEYBOARD_FORMATS } from '../ui-components/components/Keyboard' import PasswordSwitch from './PasswordSwitch'; -import { login } from '../api/AppCatalog'; +import { login, getCatalogServerURL } from '../api/AppCatalog'; export default class AppCatalogLoginComponent extends Lightning.Component { @@ -40,31 +40,49 @@ export default class AppCatalogLoginComponent extends Lightning.Component { _active() { this.hidePasswd = true this.star = "" + this.catalogURL = null + this.catalogURLState = 'loading' + this.tag('CatalogURLValue').text.text = Language.translate('Loading...') this.tag("Keyboard").visible = false + getCatalogServerURL() + .then(url => { + this.catalogURL = url || null + this.catalogURLState = url ? 'loaded' : 'not-set' + this.tag('CatalogURLValue').text.text = url || Language.translate('Unknown') + }) + .catch(() => { + this.catalogURL = null + this.catalogURLState = 'error' + this.tag('CatalogURLValue').text.text = Language.translate('Unavailable') + }) + } + + _firstEnable() { + this.spinnerAnimation = this.tag('LoadingOverlay.Spinner').animation({ + duration: 3, + repeat: -1, + stopMethod: 'immediate', + stopDelay: 0.2, + actions: [{ p: 'rotation', v: { sm: 0, 0: 0, 1: Math.PI * 2 } }], + }) + } + + _updateConnectButtonColor() { + if (this.textCollection && this.textCollection['EnterUsername'] && this.textCollection['EnterPassword']) { + this.tag('ConnectButton').color = 0xff00aa00 + } else { + this.tag('ConnectButton').color = 0xff444444 + } } handleDone() { this.tag("Keyboard").visible = false if (!this.textCollection['EnterUsername']) { this._setState("EnterUsername"); - } - else if (!this.textCollection['EnterPassword']) { + } else if (!this.textCollection['EnterPassword']) { this._setState("EnterPassword"); - } - else { - this.LOG('App Catalog Login - credentials submitted') - login(this.textCollection['EnterUsername'], this.textCollection['EnterPassword']) - .then(result => { - if (result) { - this.LOG('Login successful - navigating back') - if (!Router.isNavigating()) { - Router.back() - } - } else { - this.ERR('Login failed') - } - }) - .catch(err => this.ERR('Login error: ' + err)) + } else { + this._setState("ConnectButton"); } } @@ -89,9 +107,32 @@ export default class AppCatalogLoginComponent extends Lightning.Component { BorderTop: { x: 190, y: 130, w: 1488, h: 2, rect: true, }, + CatalogURLLabel: { + x: 190, + y: 148, + text: { + text: Language.translate("App Catalog URL") + ": ", + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xff808080, + }, + }, + CatalogURLValue: { + x: 525, + y: 148, + text: { + text: Language.translate("Loading..."), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xff808080, + wordWrapWidth: 1200, + wordWrap: false, + textOverflow: 'ellipsis', + }, + }, Username: { x: 190, - y: 170, + y: 230, text: { text: Language.translate("Username") + ": ", fontFace: CONFIG.language.font, @@ -100,12 +141,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, UsernameBox: { x: 425, - y: 160, + y: 220, texture: Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) }, UsernameText: { x: 445, - y: 170, + y: 230, zIndex: 2, text: { text: '', @@ -119,7 +160,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, Password: { x: 190, - y: 240, + y: 300, text: { text: Language.translate("Password") + ":", fontFace: CONFIG.language.font, @@ -128,12 +169,12 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, PasswordBox: { x: 425, - y: 230, + y: 290, texture: Lightning.Tools.getRoundRect(1248, 58, 0, 3, 0xffffffff, false) }, Pwd: { x: 445, - y: 240, + y: 300, zIndex: 2, text: { text: '', @@ -146,11 +187,11 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, }, BorderBottom: { - x: 190, y: 326, w: 1488, h: 2, rect: true, + x: 190, y: 386, w: 1488, h: 2, rect: true, }, ExitButton: { - x: 960, - y: 350, + x: 740, + y: 410, mountX: 0.5, w: 200, h: 50, @@ -169,9 +210,30 @@ export default class AppCatalogLoginComponent extends Lightning.Component { }, }, }, + ConnectButton: { + x: 1180, + y: 410, + mountX: 0.5, + w: 200, + h: 50, + rect: true, + color: 0xff444444, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 10 }, + ConnectLabel: { + x: 100, + y: 25, + mount: 0.5, + text: { + text: Language.translate('Connect'), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xffffffff, + }, + }, + }, Keyboard: { - y: 420, - x: 425, + y: 480, + x: 400, type: Keyboard, visible: false, zIndex: 2, @@ -180,22 +242,145 @@ export default class AppCatalogLoginComponent extends Lightning.Component { PasswrdSwitch: { h: 45, w: 66.9, - x: 1642, - y: 260, + x: 1617, + y: 320, zIndex: 2, type: PasswordSwitch, mount: 0.5, visible: true }, ShowPassword: { - x: 1365, - y: 242, + x: 1350, + y: 302, w: 300, h: 75, zIndex: 2, text: { text: Language.translate('Show Password'), fontSize: 25, fontFace: CONFIG.language.font, textColor: 0xffffffff, textAlign: 'left' }, visible: true - } + }, + AuthFailedPopup: { + x: 960, + y: 540, + mount: 0.5, + w: 560, + h: 200, + rect: true, + color: 0xff222222, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 12 }, + visible: false, + zIndex: 11, + PopupText: { + x: 280, + y: 60, + mountX: 0.5, + text: { + text: Language.translate('Authentication failed. Please try again.'), + fontFace: CONFIG.language.font, + fontSize: 26, + textColor: 0xffffffff, + textAlign: 'center', + wordWrapWidth: 500, + wordWrap: true, + }, + }, + OkButton: { + x: 280, + y: 145, + mountX: 0.5, + mountY: 0.5, + w: 150, + h: 46, + rect: true, + color: 0xff444444, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 10 }, + OkLabel: { + x: 75, + y: 23, + mount: 0.5, + text: { + text: Language.translate('OK'), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xffffffff, + }, + }, + }, + }, + URLNotSetPopup: { + x: 960, + y: 540, + mount: 0.5, + w: 560, + h: 200, + rect: true, + color: 0xff222222, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 12 }, + visible: false, + zIndex: 11, + PopupText: { + x: 280, + y: 60, + mountX: 0.5, + text: { + text: Language.translate('App Catalog URL is not set'), + fontFace: CONFIG.language.font, + fontSize: 26, + textColor: 0xffffffff, + textAlign: 'center', + wordWrapWidth: 500, + wordWrap: true, + }, + }, + OkButton: { + x: 280, + y: 145, + mountX: 0.5, + mountY: 0.5, + w: 150, + h: 46, + rect: true, + color: 0xff444444, + shader: { type: Lightning.shaders.RoundedRectangle, radius: 10 }, + OkLabel: { + x: 75, + y: 23, + mount: 0.5, + text: { + text: Language.translate('OK'), + fontFace: CONFIG.language.font, + fontSize: 22, + textColor: 0xffffffff, + }, + }, + }, + }, + LoadingOverlay: { + w: 1920, + h: 1080, + rect: true, + color: 0xCC000000, + visible: false, + zIndex: 10, + Spinner: { + x: 920, + y: 490, + w: 80, + h: 80, + mount: 0.5, + src: Utils.asset('images/settings/Loading.png'), + }, + AuthText: { + x: 960, + y: 550, + mountX: 0.5, + text: { + text: Language.translate('Authenticating...'), + fontFace: CONFIG.language.font, + fontSize: 28, + textColor: 0xffffffff, + }, + }, + }, } } @@ -206,6 +391,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.tag("UsernameText").text.text = Language.translate("Press OK to enter Username"); this.tag('UsernameText').text.textColor = 0xff808080 this.tag('Pwd').text.textColor = 0xff808080 + this._updateConnectButtonColor() } encrypt() { @@ -315,12 +501,130 @@ export default class AppCatalogLoginComponent extends Lightning.Component { _handleDown() { this._setState('EnterUsername') } + _handleRight() { + this._setState('ConnectButton') + } _handleEnter() { if (!Router.isNavigating()) { Router.back() } } }, + class ConnectButton extends this { + $enter() { + this.tag('ConnectButton').color = (this.textCollection['EnterUsername'] && this.textCollection['EnterPassword']) + ? 0xff00cc00 + : 0xff444444 + } + $exit() { + this._updateConnectButtonColor() + } + _handleUp() { + this._setState('EnterPassword') + } + _handleDown() { + this._setState('EnterUsername') + } + _handleLeft() { + this._setState('ExitButton') + } + _handleEnter() { + this.tag('Keyboard').visible = false + if (this.catalogURLState === 'loading') { + this.LOG('Catalog URL still loading, please wait...') + return + } + if (this.catalogURLState === 'error' || this.catalogURLState === 'not-set' || !this.catalogURL) { + this._setState('URLNotSetPopup') + return + } + if (!this.textCollection['EnterUsername']) { + this._setState('EnterUsername') + return + } + if (!this.textCollection['EnterPassword']) { + this._setState('EnterPassword') + return + } + this._setState('Authenticating') + login(this.textCollection['EnterUsername'], this.textCollection['EnterPassword']) + .then(result => { + if (result) { + this.LOG('Login successful - navigating to menu') + if (!Router.isNavigating()) { + Router.navigate('menu') + } + } else { + this.ERR('Login failed') + setTimeout(() => this._setState('AuthFailedPopup'), 0) + } + }) + .catch(err => { + this.ERR('Login error: ' + err) + setTimeout(() => this._setState('AuthFailedPopup'), 0) + }) + } + }, + class AuthFailedPopup extends this { + $enter() { + this.tag('AuthFailedPopup').visible = true + this.tag('AuthFailedPopup.OkButton').color = CONFIG.theme.hex + } + $exit() { + this.tag('AuthFailedPopup').visible = false + this.tag('AuthFailedPopup.OkButton').color = 0xff444444 + } + _handleEnter() { + this._setState('ConnectButton') + } + _handleBack() { + this._setState('ConnectButton') + } + _handleUp() {} + _handleDown() {} + _handleLeft() {} + _handleRight() {} + }, + class URLNotSetPopup extends this { + $enter() { + this.tag('URLNotSetPopup').visible = true + this.tag('URLNotSetPopup.OkButton').color = CONFIG.theme.hex + const msg = this.catalogURLState === 'error' + ? Language.translate('Unable to retrieve App Catalog URL') + : Language.translate('App Catalog URL is not set') + this.tag('URLNotSetPopup.PopupText').text.text = msg + } + $exit() { + this.tag('URLNotSetPopup').visible = false + this.tag('URLNotSetPopup.OkButton').color = 0xff444444 + } + _handleEnter() { + this._setState('ConnectButton') + } + _handleBack() { + this._setState('ConnectButton') + } + _handleUp() {} + _handleDown() {} + _handleLeft() {} + _handleRight() {} + }, + class Authenticating extends this { + $enter() { + this.tag('LoadingOverlay').visible = true + this.spinnerAnimation.start() + } + $exit() { + this.spinnerAnimation.stop() + this.tag('LoadingOverlay').visible = false + } + _handleEnter() {} + _handleBack() {} + _handleUp() {} + _handleDown() {} + _handleLeft() {} + _handleRight() {} + }, class Keyboard extends this { $enter(state) { this.prevState = state.prevState @@ -361,6 +665,7 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.star += (this.prevState === "EnterPassword") ? '\u25CF' : '' this.tag(this.element).text.text = this.encrypt() ? this.star : this.textCollection[this.prevState]; } + this._updateConnectButtonColor() } _handleUp() { this._setState(this.prevState) @@ -378,5 +683,6 @@ export default class AppCatalogLoginComponent extends Lightning.Component { this.textCollection = { 'EnterUsername': '', 'EnterPassword': '' } this.tag("Pwd").text.text = this.textCollection['EnterPassword'] this.tag("UsernameText").text.text = this.textCollection['EnterUsername'] + this.tag('ConnectButton').color = 0xff444444 } } diff --git a/accelerator-home-ui/static/language/translations/en.json b/accelerator-home-ui/static/language/translations/en.json index 427ed25..aa9dbd9 100644 --- a/accelerator-home-ui/static/language/translations/en.json +++ b/accelerator-home-ui/static/language/translations/en.json @@ -1,6 +1,7 @@ { "en" : "English", "es": "Spanish", + "OK": "OK", "home": "Home", "click to launch": "click to launch", "wifi": "WiFi Settings", @@ -123,5 +124,16 @@ "INVALID_CREDENTIALS - The connection failed due to invalid credentials":"", "NO_SSID - The SSID does not exist":"", "UNKNOWN - Any other error":"", - "Configuring as default":"Configuring as default" + "Configuring as default":"Configuring as default", + "Loading...":"Loading...", + "Authenticating...":"Authenticating...", + "Unknown":"Unknown", + "Unavailable":"Unavailable", + "App Catalog URL is not set":"App Catalog URL is not set", + "Unable to retrieve App Catalog URL":"Unable to retrieve App Catalog URL", + "Authentication failed. Please try again.":"Authentication failed. Please try again.", + "Connect to the Application Catalog":"Connect to the Application Catalog", + "App Catalog URL":"App Catalog URL", + "Press OK to enter Username":"Press OK to enter Username", + "Exit":"Exit" } \ No newline at end of file diff --git a/accelerator-home-ui/static/language/translations/es.json b/accelerator-home-ui/static/language/translations/es.json index ad17c49..d856c63 100644 --- a/accelerator-home-ui/static/language/translations/es.json +++ b/accelerator-home-ui/static/language/translations/es.json @@ -295,5 +295,14 @@ "Are you sure you want to uninstall this app?":"¿Está seguro de que desea desinstalar esta aplicación?", "Press OK to enter Username":"Presione OK para ingresar el nombre de usuario", "Username":"Nombre de usuario", - "Downloading":"Descargando" + "Downloading":"Descargando", + "Authentication failed. Please try again.":"Autenticación fallida. Por favor, inténtelo de nuevo.", + "Exit":"Salir", + "App Catalog URL":"URL del catálogo de aplicaciones", + "Loading...":"Cargando...", + "Authenticating...":"Autenticando...", + "Unknown":"Desconocido", + "Unavailable":"No disponible", + "App Catalog URL is not set":"La URL del catálogo de aplicaciones no está configurada", + "Unable to retrieve App Catalog URL":"No se pudo obtener la URL del catálogo de aplicaciones" } diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index c64ed36..927a96f 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.12", - "versionName": "6.0.12", + "version": "6.0.13", + "versionName": "6.0.13", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From 68f72deb6c4986fa02e9c7fc5082418f7e5b72e7 Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:06:40 +0530 Subject: [PATCH 49/52] RDKEAPPRT - 795 Factory reset is not removing installed apps, application catalogue credentials,saved WiFi details, Audio and Video settings (#202) * RDKEAPPRT-795 Factory reset is not removing installed apps, application catalogue credentials,saved WiFi details, Audio and Video settings * Added changes for version in bolt * Addressed the review comments * Addressed the review comments * Addressed the review comments * Addressed the review comments * Addressed the review comments * Addressed the review comments * Addressed the review comments * Addressed the review comments --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/api/WarehouseApis.js | 9 +- .../FactoryResetConfirmationScreen.js | 98 +++++++------------ .../package-configs/com.rdkcentral.refui.json | 4 +- 4 files changed, 47 insertions(+), 66 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 5ee2e54..356304c 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.13" + "version": "6.0.14" } } diff --git a/accelerator-home-ui/src/api/WarehouseApis.js b/accelerator-home-ui/src/api/WarehouseApis.js index 2c3ef90..43c4621 100644 --- a/accelerator-home-ui/src/api/WarehouseApis.js +++ b/accelerator-home-ui/src/api/WarehouseApis.js @@ -121,14 +121,17 @@ export default class Warehouse { }) } - resetDevice(resetType = "USERFACTORY", suppressReboot = "false") { + resetDevice(resetType = "WAREHOUSE_CLEAR", suppressReboot = false) { return new Promise((resolve, reject) => { let params = { resetType: resetType, suppressReboot: suppressReboot} this.INFO(this.callsign + " resetDevice params: " + JSON.stringify(params)); this.thunder.call(this.callsign, 'resetDevice', params).then(result => { this.INFO(this.callsign + " resetDevice result: " + JSON.stringify(result)) - if (result.success)resolve(result.success) - reject(false) + if (result.success) { + resolve(result.success) + } else { + reject(false) + } }).catch(err => { this.ERR(this.callsign + " resetDevice error: " + JSON.stringify(err)) Metrics.error(Metrics.ErrorType.OTHER,"WarehouseApiError", "Error while Thunder warehouseApi resetDevice "+JSON.stringify(err), false, null) diff --git a/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js b/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js index fa94a09..2e0c760 100644 --- a/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js +++ b/accelerator-home-ui/src/screens/OtherSettingsScreens/FactoryResetConfirmationScreen.js @@ -18,16 +18,12 @@ **/ import { Lightning, Utils, Router, Language } from '@lightningjs/sdk' import AppApi from '../../api/AppApi' -import BluetoothApi from '../../api/BluetoothApi' import { CONFIG,GLOBALS } from '../../Config/Config' -import WiFi from '../../api/WifiApi' -import NetworkManager from '../../api/NetworkManagerAPI.js' import AlexaApi from '../../api/AlexaApi.js'; import RCApi from '../../api/RemoteControl' import Warehouse from '../../api/WarehouseApis.js' const appApi = new AppApi() -const _btApi = new BluetoothApi() /** * Class for Reboot Confirmation Screen. @@ -126,10 +122,6 @@ export default class RebootConfirmationScreen extends Lightning.Component { } } - _init() { - this.AppApi = new AppApi() - } - _focus() { this._setState('Confirm') this.loadingAnimation = this.tag('Loader').animation({ @@ -140,12 +132,16 @@ export default class RebootConfirmationScreen extends Lightning.Component { _firstEnable() { - this.AppApi.checkStatus(Warehouse.get().callsign).then(resp => { - this.LOG("FactoryReset: warehouse plugin status : " + JSON.stringify(resp[0].status)); - if (resp[0].status != 'activated') { - Warehouse.get().activate().catch(err => { - this.ERR("FactoryReset: warehouse plugin activation failed; feature may not work." + JSON.stringify(err)); - }); + appApi.checkStatus(Warehouse.get().callsign).then(resp => { + if (resp && resp[0] && resp[0].state) { + this.LOG("FactoryReset: warehouse plugin state: " + JSON.stringify(resp[0].state)); + if (resp[0].state !== 'activated') { + Warehouse.get().activate().catch(err => { + this.ERR("FactoryReset: warehouse plugin activation failed; feature may not work." + JSON.stringify(err)); + }); + } + } else { + this.WARN("FactoryReset: unexpected checkStatus response: " + JSON.stringify(resp)); } }); } @@ -161,53 +157,9 @@ export default class RebootConfirmationScreen extends Lightning.Component { AlexaApi.get().disableSmartScreen(); if(GLOBALS.AlexaAvsstatus){AlexaApi.get().resetAVSCredentials();} AlexaApi.get().setAlexaAuthStatus("AlexaAuthPending"); - let getsuportedmode = await appApi.getSupportedAudioPorts(); - for (let i = 0; i < getsuportedmode.supportedAudioPorts.length; i++) { - if(getsuportedmode.supportedAudioPorts[i] != 'SPDIF0'){ - let rsbass = await appApi.resetBassEnhancer(getsuportedmode.supportedAudioPorts[i]).catch((err) =>{ this.ERR("resetBassEnhancer" + JSON.stringify(err)) }); - if (rsbass.success != true) { this.LOG("resetBassEnhancer" + JSON.stringify(rsbass)) } - let rsDialog = await appApi.resetDialogEnhancement(getsuportedmode.supportedAudioPorts[i]).catch((err) =>{ this.ERR("resetDialogEnhancement" + JSON.stringify(err)) }) - if (rsDialog.success != true) { this.LOG("resetDialogEnhancement" + JSON.stringify(rsDialog)) } - let rsVirtualizer = await appApi.resetSurroundVirtualizer(getsuportedmode.supportedAudioPorts[i]).catch(err =>{ this.ERR("resetSurroundVirtualizer" + JSON.stringify(err)) }); - if (rsVirtualizer.success != true) { this.LOG("resetSurroundVirtualizer" + JSON.stringify(rsVirtualizer)) } - let rsvolumelvel = await appApi.resetVolumeLeveller(getsuportedmode.supportedAudioPorts[i]).catch(err =>{ this.ERR("resetVolumeLeveller" + JSON.stringify(err)) }); - if (rsvolumelvel.success != true) { this.LOG("resetVolumeLeveller" + JSON.stringify(rsvolumelvel)) } - } - } - let btActivate = await _btApi.btactivate().then(result => this.LOG("Btactivate" + JSON.stringify(result))).catch(err=> this.ERR("error while activating bluetooth")) - let getPairedDevices = await _btApi.getPairedDevices().then(res=>res).catch(err => 0) - this.LOG("getpairedDevices" + JSON.stringify(getPairedDevices)) - for(let i=0 ; i 0){ - let btunpair = await _btApi.unpair(getPairedDevices[i].deviceId).catch(err => { this.ERR("btunpair" + JSON.stringify(err)) }); - if(btunpair.success != true){ this.LOG("btunpair" + JSON.stringify(btunpair)) } - } - } - await RCApi.get().activate().then(()=>{ RCApi.get().factoryReset(); }).catch(err => this.ERR("error while resetting remote control" + JSON.stringify(err))); - let contollerStat = await appApi.checkStatus("Monitor") - for(let i=0; i< contollerStat[0].configuration.observables.length; i++){ - let monitorstat = await appApi.monitorStatus(contollerStat[0].configuration.observables[i].callsign).catch(err =>{ this.ERR("monitorStatus" + JSON.stringify(err)) }); - if(monitorstat.length < 0){ this.LOG("monitorStatus" + JSON.stringify(monitorstat)) } - } - await Warehouse.get().internalReset().catch(err => { this.ERR("internalReset" + JSON.stringify(err)) }); - await Warehouse.get().isClean().catch(err => { this.ERR("isClean" + JSON.stringify(err)) }); - await Warehouse.get().lightReset().catch(err => { this.ERR("lightReset" + JSON.stringify(err))}); - await Warehouse.get().resetDevice().catch(err => { this.ERR("resetDevice" + JSON.stringify(err)) }); - + await RCApi.get().activate().then(()=> RCApi.get().factoryReset()).catch(err => this.ERR("error while resetting remote control" + JSON.stringify(err))); let rsactivitytime = await appApi.resetInactivityTime().catch(err => { this.ERR("resetInactivityTime" + JSON.stringify(err)) }); if (rsactivitytime != null) { this.LOG("rsactivitytime" + JSON.stringify(rsactivitytime)) } - let GetKnownSSIDs = await NetworkManager.GetKnownSSIDs().then((ssids)=>{ssids}).catch(err => { console.error("GetKnownssids",err) }); - let clearSSID =false - if(GetKnownSSIDs && GetKnownSSIDs.length>0) - { - for(let i=0;i { this.ERR("clearSSID" + JSON.stringify(err)) });} - } - } - if (clearSSID != true) { this.LOG("clearSSID" + JSON.stringify(clearSSID)) } - let wifidisconnect = await NetworkManager.WiFiDisconnect().catch(err =>{ this.ERR("wifidisconnect" + JSON.stringify(err)) }); - if (wifidisconnect.success != true) { this.LOG("wifidisconnect" + JSON.stringify(wifidisconnect)) } try { localStorage.clear(); this.LOG("localStorage cleared successfully"); @@ -216,7 +168,33 @@ export default class RebootConfirmationScreen extends Lightning.Component { this.ERR("Error clearing localStorage: " + JSON.stringify(err)); } await appApi.clearCache().catch(err => { this.ERR("clearCache error: " + JSON.stringify(err)) }) - await appApi.reboot("User Trigger").then(result => { this.LOG('device rebooting' + JSON.stringify(result))}) + // Ensure Warehouse plugin is activated before calling resetDevice. + let warehouseStatus = await appApi.checkStatus(Warehouse.get().callsign); + let isActivated = warehouseStatus && warehouseStatus[0] && warehouseStatus[0].state === 'activated'; + if (!isActivated) { + if (!warehouseStatus || !warehouseStatus[0] || !warehouseStatus[0].state) { + this.WARN("FactoryReset: checkStatus returned unexpected response: " + JSON.stringify(warehouseStatus) + "; attempting activation."); + } else { + this.LOG("FactoryReset: Warehouse state is '" + warehouseStatus[0].state + "'; activating."); + } + let activationSuccess = await Warehouse.get().activate().then(() => true).catch(err => { + this.ERR("FactoryReset: warehouse activation failed: " + JSON.stringify(err)); + return false; + }); + if (!activationSuccess) { + this.ERR("FactoryReset: cannot proceed without Warehouse plugin."); + this.tag("Title").text.text = Language.translate("Factory Reset"); + this.tag("Info").text.text = Language.translate("Factory Reset failed. Please try again."); + this._setState('Confirm'); + return; + } + } + await Warehouse.get().resetDevice().catch(err => { + this.ERR("resetDevice" + JSON.stringify(err)); + this.tag("Title").text.text = Language.translate("Factory Reset"); + this.tag("Info").text.text = Language.translate("Factory Reset failed. Please try again."); + this._setState('Confirm'); + }); } static _states() { diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 927a96f..b358892 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.13", - "versionName": "6.0.13", + "version": "6.0.14", + "versionName": "6.0.14", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From 18308534836e58e7123bee5b86025013a51c82da Mon Sep 17 00:00:00 2001 From: suryag23 <141610966+suryag23@users.noreply.github.com> Date: Thu, 11 Jun 2026 10:49:32 +0530 Subject: [PATCH 50/52] RDKEAPPRT-744 Screen Saver works but there is no video to be played (#201) * RDKEAPPRT-744 Screen Saver works but there is no video to be played * version update in bolt package --- accelerator-home-ui/settings.json | 2 +- .../static/images/Screensaver.mp4 | Bin 0 -> 53367 bytes bolt/package-configs/com.rdkcentral.refui.json | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 accelerator-home-ui/static/images/Screensaver.mp4 diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 356304c..446344a 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.14" + "version": "6.0.15" } } diff --git a/accelerator-home-ui/static/images/Screensaver.mp4 b/accelerator-home-ui/static/images/Screensaver.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..a8176d638253a4604444d0f67bf4a6696848e087 GIT binary patch literal 53367 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 literal 0 HcmV?d00001 diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index b358892..6730ad4 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.14", - "versionName": "6.0.14", + "version": "6.0.15", + "versionName": "6.0.15", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html", From ddf35ffd7c1382757b7bf7791235aec20849908b Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 11 Jun 2026 15:46:24 +0530 Subject: [PATCH 51/52] RDKEAPPRT-833 Update System Service version in refui --- accelerator-home-ui/settings.json | 2 +- accelerator-home-ui/src/Config/Config.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/accelerator-home-ui/settings.json b/accelerator-home-ui/settings.json index 446344a..273bba9 100644 --- a/accelerator-home-ui/settings.json +++ b/accelerator-home-ui/settings.json @@ -13,6 +13,6 @@ "log": true, "enableAppSuspended": true, "showVersion": false, - "version": "6.0.15" + "version": "6.0.16" } } diff --git a/accelerator-home-ui/src/Config/Config.js b/accelerator-home-ui/src/Config/Config.js index 74df182..c397b6d 100644 --- a/accelerator-home-ui/src/Config/Config.js +++ b/accelerator-home-ui/src/Config/Config.js @@ -59,7 +59,6 @@ export var CONFIG = { port: 9998, versions: { default: 1, - 'org.rdk.System': 2, ControlSettings: 2, 'org.rdk.UsbAccess': 2, 'org.rdk.DisplaySettings': 2, From 0ba404bce16305436c757153d891d7fa9d74fab7 Mon Sep 17 00:00:00 2001 From: suryag23 Date: Thu, 11 Jun 2026 15:48:10 +0530 Subject: [PATCH 52/52] To update the version in the boltpackage --- bolt/package-configs/com.rdkcentral.refui.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bolt/package-configs/com.rdkcentral.refui.json b/bolt/package-configs/com.rdkcentral.refui.json index 6730ad4..d611e07 100644 --- a/bolt/package-configs/com.rdkcentral.refui.json +++ b/bolt/package-configs/com.rdkcentral.refui.json @@ -1,7 +1,7 @@ { "id": "com.rdkcentral.refui", - "version": "6.0.15", - "versionName": "6.0.15", + "version": "6.0.16", + "versionName": "6.0.16", "name": "RDK Ref UI Home Screen", "packageType": "application", "entryPoint": "--lightning --dev file:///usr/share/refui/index.html",