Skip to content

Commit

Permalink
RDK-38400: RDKShell Checkpoint and Restore Support
Browse files Browse the repository at this point in the history
The code is guarded by HIBERNATE_SUPPORT_ENABLED flag.
  • Loading branch information
szymon.mulczynski authored and adrianM27 committed Oct 3, 2023
1 parent 7f283bd commit 39efa06
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 2 deletions.
5 changes: 5 additions & 0 deletions RDKShell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ set(PLUGIN_RDKSHELL_EXTRA_LIBRARIES "")
set(PLUGIN_RDKSHELL_STARTUPORDER "" CACHE STRING "Automatically start RDKShell plugin")

option(PLUGIN_RDKSHELL_READ_MAC_ON_STARTUP "PLUGIN_RDKSHELL_READ_MAC_ON_STARTUP" OFF)
option(PLUGIN_HIBERNATESUPPORT "Include hibernate support in the build." OFF)

find_package(${NAMESPACE}Plugins REQUIRED)
find_package(IARMBus)
Expand Down Expand Up @@ -50,6 +51,10 @@ endif (PLUGIN_RDKSHELL_READ_MAC_ON_STARTUP)

target_compile_definitions(${MODULE_NAME} PRIVATE MODULE_NAME=Plugin_${PLUGIN_NAME})

if(PLUGIN_HIBERNATESUPPORT)
target_compile_definitions(${MODULE_NAME} PRIVATE HIBERNATE_SUPPORT_ENABLED=1)
endif()

target_include_directories(${MODULE_NAME} PRIVATE ../helpers ${IARMBUS_INCLUDE_DIRS} )

set_source_files_properties(RDKShell.cpp PROPERTIES COMPILE_FLAGS "-fexceptions")
Expand Down
132 changes: 130 additions & 2 deletions RDKShell/RDKShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_GET_AV_BLOCKED_APPS
const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_KEY_REPEAT_CONFIG = "keyRepeatConfig";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_GET_GRAPHICS_FRAME_RATE = "getGraphicsFrameRate";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_SET_GRAPHICS_FRAME_RATE = "setGraphicsFrameRate";
#ifdef HIBERNATE_SUPPORT_ENABLED
const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_CHECKPOINT = "checkpoint";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_METHOD_RESTORE = "restore";
#endif

const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_USER_INACTIVITY = "onUserInactivity";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_APP_LAUNCHED = "onApplicationLaunched";
Expand All @@ -162,6 +166,10 @@ const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_DEVICE_CRITICALLY_LO
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_EASTER_EGG = "onEasterEgg";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_WILL_DESTROY = "onWillDestroy";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_SCREENSHOT_COMPLETE = "onScreenshotComplete";
#ifdef HIBERNATE_SUPPORT_ENABLED
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_CHECKPOINTED = "onCheckpointed";
const string WPEFramework::Plugin::RDKShell::RDKSHELL_EVENT_ON_RESTORED = "onRestored";
#endif

using namespace std;
using namespace RdkShell;
Expand Down Expand Up @@ -1238,6 +1246,10 @@ namespace WPEFramework {
Register(RDKSHELL_METHOD_SET_GRAPHICS_FRAME_RATE, &RDKShell::setGraphicsFrameRateWrapper, this);
Register(RDKSHELL_METHOD_SET_AV_BLOCKED, &RDKShell::setAVBlockedWrapper, this);
Register(RDKSHELL_METHOD_GET_AV_BLOCKED_APPS, &RDKShell::getBlockedAVApplicationsWrapper, this);
#ifdef HIBERNATE_SUPPORT_ENABLED
Register(RDKSHELL_METHOD_CHECKPOINT, &RDKShell::checkpointWrapper, this);
Register(RDKSHELL_METHOD_RESTORE, &RDKShell::restoreWrapper, this);
#endif
m_timer.connect(std::bind(&RDKShell::onTimer, this));
}

Expand Down Expand Up @@ -4807,12 +4819,31 @@ namespace WPEFramework {
WPEFramework::Core::JSON::String stateString;
const string callsignWithVersion = callsign + ".1";
auto thunderPlugin = getThunderControllerClient(callsignWithVersion);
uint32_t stateStatus = thunderPlugin->Get<WPEFramework::Core::JSON::String>(RDKSHELL_THUNDER_TIMEOUT, "state", stateString);
uint32_t stateStatus = 0;

#ifdef HIBERNATE_SUPPORT_ENABLED
if(service.JSONState != PluginHost::MetaData::Service::state::HIBERNATED)
{
stateStatus = thunderPlugin->Get<WPEFramework::Core::JSON::String>(RDKSHELL_THUNDER_TIMEOUT, "state", stateString);
}
else
{
stateString = "checkpointed";
}
#endif

if (stateStatus == 0)
{
WPEFramework::Core::JSON::String urlString;
uint32_t urlStatus = thunderPlugin->Get<WPEFramework::Core::JSON::String>(RDKSHELL_THUNDER_TIMEOUT, "url",urlString);
uint32_t urlStatus = 1;
#ifdef HIBERNATE_SUPPORT_ENABLED
if(service.JSONState != PluginHost::MetaData::Service::state::HIBERNATED)
{
#endif
urlStatus = thunderPlugin->Get<WPEFramework::Core::JSON::String>(RDKSHELL_THUNDER_TIMEOUT, "url",urlString);
#ifdef HIBERNATE_SUPPORT_ENABLED
}
#endif

JsonObject typeObject;
typeObject["callsign"] = callsign;
Expand Down Expand Up @@ -5917,6 +5948,103 @@ namespace WPEFramework {
returnResponse(status);
}

#ifdef HIBERNATE_SUPPORT_ENABLED
uint32_t RDKShell::checkpointWrapper(const JsonObject& parameters, JsonObject& response)
{
LOGINFOMETHOD();
bool status = false;
if (parameters.HasLabel("callsign"))
{
std::string callsign = parameters["callsign"].String();
bool isApplicationBeingDestroyed = false;

gLaunchDestroyMutex.lock();
if (gDestroyApplications.find(callsign) != gDestroyApplications.end())
{
isApplicationBeingDestroyed = true;
}
if (gExternalDestroyApplications.find(callsign) != gExternalDestroyApplications.end())
{
isApplicationBeingDestroyed = true;
}
gLaunchDestroyMutex.unlock();

if (isApplicationBeingDestroyed)
{
std::cout << "ignoring checkpoint for " << callsign << " as it is being destroyed " << std::endl;
status = false;
response["message"] = "failed to checkpoint application, is being destroyed";
returnResponse(status);
}

std::thread requestsThread =
std::thread([=]()
{
auto thunderController = RDKShell::getThunderControllerClient();
JsonObject request, result, eventMsg;
request["callsign"] = callsign;
request["timeout"] = RDKSHELL_THUNDER_TIMEOUT;
if(parameters.HasLabel("timeout"))
{
request["timeout"] = parameters["timeout"];
}
if(parameters.HasLabel("procsequence"))
{
request["procsequence"] = parameters["procsequence"];
}
uint32_t errCode = thunderController->Invoke<JsonObject, JsonObject>(RDKSHELL_THUNDER_TIMEOUT, "hibernate", request, result);
if(errCode > 0)
{
eventMsg["success"] = false;
eventMsg["message"] = result;
}
else
{
eventMsg["success"] = true;
}
notify(RDKShell::RDKSHELL_EVENT_ON_CHECKPOINTED, eventMsg);
});
requestsThread.detach();
status = true;
}

returnResponse(status);
}

uint32_t RDKShell::restoreWrapper(const JsonObject& parameters, JsonObject& response)
{
LOGINFOMETHOD();
bool status = false;
if (parameters.HasLabel("callsign"))
{
std::string callsign = parameters["callsign"].String();
std::thread requestsThread =
std::thread([=]()
{
auto thunderController = RDKShell::getThunderControllerClient();
JsonObject request, result, eventMsg;
request["callsign"] = callsign;

uint32_t errCode = thunderController->Invoke<JsonObject, JsonObject>(RDKSHELL_THUNDER_TIMEOUT, "activate", request, result);
if(errCode > 0)
{
eventMsg["success"] = false;
eventMsg["message"] = result;
}
else
{
eventMsg["success"] = true;
}
notify(RDKShell::RDKSHELL_EVENT_ON_RESTORED, eventMsg);
});
requestsThread.detach();
status = true;
}

returnResponse(status);
}
#endif

// Registered methods end

// Events begin
Expand Down
12 changes: 12 additions & 0 deletions RDKShell/RDKShell.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ namespace WPEFramework {
static const string RDKSHELL_METHOD_KEY_REPEAT_CONFIG;
static const string RDKSHELL_METHOD_GET_GRAPHICS_FRAME_RATE;
static const string RDKSHELL_METHOD_SET_GRAPHICS_FRAME_RATE;
#ifdef HIBERNATE_SUPPORT_ENABLED
static const string RDKSHELL_METHOD_CHECKPOINT;
static const string RDKSHELL_METHOD_RESTORE;
#endif

// events
static const string RDKSHELL_EVENT_ON_USER_INACTIVITY;
Expand All @@ -167,6 +171,10 @@ namespace WPEFramework {
static const string RDKSHELL_EVENT_ON_EASTER_EGG;
static const string RDKSHELL_EVENT_ON_WILL_DESTROY;
static const string RDKSHELL_EVENT_ON_SCREENSHOT_COMPLETE;
#ifdef HIBERNATE_SUPPORT_ENABLED
static const string RDKSHELL_EVENT_ON_CHECKPOINTED;
static const string RDKSHELL_EVENT_ON_RESTORED;
#endif

void notify(const std::string& event, const JsonObject& parameters);
void pluginEventHandler(const JsonObject& parameters);
Expand Down Expand Up @@ -261,6 +269,10 @@ namespace WPEFramework {
uint32_t keyRepeatConfigWrapper(const JsonObject& parameters, JsonObject& response);
uint32_t getGraphicsFrameRateWrapper(const JsonObject& parameters, JsonObject& response);
uint32_t setGraphicsFrameRateWrapper(const JsonObject& parameters, JsonObject& response);
#ifdef HIBERNATE_SUPPORT_ENABLED
uint32_t checkpointWrapper(const JsonObject& parameters, JsonObject& response);
uint32_t restoreWrapper(const JsonObject& parameters, JsonObject& response);
#endif

private/*internal methods*/:
RDKShell(const RDKShell&) = delete;
Expand Down
89 changes: 89 additions & 0 deletions RDKShell/RDKShell.json
Original file line number Diff line number Diff line change
Expand Up @@ -2232,6 +2232,59 @@
"success"
]
}
},
"checkpoint": {
"summary": "Checkpoint an application.",
"events": {
"onCheckpointed" : "Triggers when an application is checkpointed"
},
"params": {
"type": "object",
"properties":{
"callsign": {
"$ref": "#/definitions/callsign"
},
"timeout": {
"summary": "Timeout in ms for checkpoint procedure",
"type": "number",
"example": 10000
},
"procsequence": {
"summary": "Checkpoint sequence of application processes",
"type": "array",
"items": {
"type": "string",
"example": "LightningApp-0"
}
}
},
"required": [
"callsign"
]
},
"result": {
"$ref": "#/common/result"
}
},
"restore": {
"summary": "Restore an application.",
"events": {
"onRestored" : "Triggers when an application is restored"
},
"params": {
"type": "object",
"properties":{
"callsign": {
"$ref": "#/definitions/callsign"
}
},
"required": [
"callsign"
]
},
"result": {
"$ref": "#/common/result"
}
}
},
"events": {
Expand Down Expand Up @@ -2545,6 +2598,42 @@
"client"
]
}
},
"onCheckpointed":{
"summary": "Triggers when an application is checkpointed.",
"params": {
"type": "object",
"properties": {
"callsign":{
"$ref": "#/definitions/callsign"
},
"success": {
"$ref": "#/common/success"
}
},
"required": [
"callsign",
"success"
]
}
},
"onRestored":{
"summary": "Triggers when an application is restored.",
"params": {
"type": "object",
"properties": {
"callsign":{
"$ref": "#/definitions/callsign"
},
"success": {
"$ref": "#/common/success"
}
},
"required": [
"callsign",
"success"
]
}
}
}
}

0 comments on commit 39efa06

Please sign in to comment.