//WRT INCLUDES
#include <dpl/log/log.h>
+#include <dpl/foreach.h>
#include <job.h>
#include "plugin_install_task.h"
#include "job_plugin_install.h"
#include <dpl/wrt-dao-rw/feature_dao.h>
#include <dpl/wrt-dao-rw/plugin_dao.h>
#include "plugin_objects.h"
+#include <wrt_plugin_export.h>
using namespace WrtDB;
m_context->installerTask->UpdateProgress( \
PluginInstallerContext::step, desc);
+#define DISABLE_IF_PLUGIN_WITHOUT_LIB() \
+ if (m_pluginInfo.m_libraryName.empty()) \
+ { \
+ LogWarning("Plugin without library."); \
+ return; \
+ }
+
namespace Jobs {
namespace PluginInstall {
PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) :
DPL::TaskDecl<PluginInstallTask>(this),
- m_context(inCont)
+ m_context(inCont),
+ m_pluginHandle(0),
+ m_dataFromConfigXML(true)
{
AddStep(&PluginInstallTask::stepCheckPluginPath);
AddStep(&PluginInstallTask::stepParseConfigFile);
+ AddStep(&PluginInstallTask::stepFindPluginLibrary);
AddStep(&PluginInstallTask::stepCheckIfAlreadyInstalled);
AddStep(&PluginInstallTask::stepLoadPluginLibrary);
AddStep(&PluginInstallTask::stepRegisterPlugin);
}
PluginInstallTask::~PluginInstallTask()
-{
-}
+{}
void PluginInstallTask::stepCheckPluginPath()
{
{
LogInfo("Plugin installation: step parse config file");
+ struct stat tmp;
+
std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
std::string(GlobalConfig::GetPluginMetafileName());
+ if (-1 == stat(filename.c_str(), &tmp)) {
+ m_dataFromConfigXML = false;
+ return;
+ }
+
LogInfo("Plugin Config file::" << filename);
Try
{
PluginMetafileReader reader;
reader.initialize(filename);
- reader.read(m_pluginMetafile);
+ reader.read(m_pluginInfo);
+
+ FOREACH(it, m_pluginInfo.m_featureContainer)
+ {
+ LogDebug("Parsed feature : " << it->m_name);
+ FOREACH(devCap, it->m_deviceCapabilities) {
+ LogDebug(" | DevCap : " << *devCap);
+ }
+ }
SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Config file analyzed");
}
}
}
+void PluginInstallTask::stepFindPluginLibrary()
+{
+ if (m_dataFromConfigXML) {
+ return;
+ }
+ LogDebug("Plugin installation: step find plugin library");
+ std::string pluginPath = m_context->pluginFilePath;
+ size_t indexpos = pluginPath.find_last_of('/');
+
+ if (std::string::npos == indexpos) {
+ indexpos = 0;
+ } else {
+ indexpos += 1; // move after '/'
+ }
+
+ std::string libName = pluginPath.substr(indexpos);
+ libName = GlobalConfig::GetPluginPrefix() + libName +
+ GlobalConfig::GetPluginSuffix();
+ LogDebug("Plugin .so: " << libName);
+ m_pluginInfo.m_libraryName = libName;
+}
+
void PluginInstallTask::stepCheckIfAlreadyInstalled()
{
- if (PluginDAO::isPluginInstalled(m_pluginMetafile.m_libraryName)) {
+ if (PluginDAO::isPluginInstalled(m_pluginInfo.m_libraryName)) {
ThrowMsg(Exceptions::PluginAlreadyInstalled,
"Plugin already installed");
}
{
LogInfo("Plugin installation: step load library");
+ DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
- m_pluginMetafile.m_libraryName;
+ m_pluginInfo.m_libraryName;
LogDebug("Loading plugin: " << filename);
void *dlHandle = dlopen(filename.c_str(), RTLD_LAZY);
- if (dlHandle == NULL ) {
+ if (dlHandle == NULL) {
+ const char* error = (const char*)dlerror();
LogError(
- "Failed to load plugin: " << filename <<
- ". Reason: " << dlerror());
+ "Failed to load plugin: " << filename <<
+ ". Reason: " << (error != NULL ? error : "unknown"));
ThrowMsg(Exceptions::PluginLibraryError, "Library error");
}
- const class_definition_t *rawClassList = NULL;
- get_widget_class_map_proc *getWidgetClassMapProcPtr = NULL;
+ const js_entity_definition_t *rawEntityList = NULL;
+ get_widget_entity_map_proc *getWidgetEntityMapProcPtr = NULL;
- getWidgetClassMapProcPtr =
- reinterpret_cast<get_widget_class_map_proc *>(dlsym(dlHandle,
- PLUGIN_GET_CLASS_MAP_PROC_NAME));
+ getWidgetEntityMapProcPtr =
+ reinterpret_cast<get_widget_entity_map_proc *>(dlsym(dlHandle,
+ PLUGIN_GET_CLASS_MAP_PROC_NAME));
- if (getWidgetClassMapProcPtr) {
- rawClassList = (*getWidgetClassMapProcPtr)();
+ if (getWidgetEntityMapProcPtr) {
+ rawEntityList = (*getWidgetEntityMapProcPtr)();
} else {
- rawClassList =
- static_cast<const class_definition_t *>(dlsym(dlHandle,
- PLUGIN_CLASS_MAP_NAME));
+ rawEntityList =
+ static_cast<const js_entity_definition_t *>(dlsym(dlHandle,
+ PLUGIN_CLASS_MAP_NAME));
}
- if (rawClassList == NULL) {
+ if (rawEntityList == NULL) {
dlclose(dlHandle);
LogError("Failed to read class name" << filename);
ThrowMsg(Exceptions::PluginLibraryError, "Library error");
}
+ if (!m_dataFromConfigXML) {
+ on_widget_init_proc *onWidgetInitProc =
+ reinterpret_cast<on_widget_init_proc *>(
+ dlsym(dlHandle, PLUGIN_WIDGET_INIT_PROC_NAME));
+
+ if (NULL == onWidgetInitProc) {
+ dlclose(dlHandle);
+ LogError("Failed to read onWidgetInit symbol" << filename);
+ ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+ }
+
+ // obtain feature -> dev-cap mapping
+ feature_mapping_interface_t mappingInterface = { NULL, NULL, NULL };
+ (*onWidgetInitProc)(&mappingInterface);
+
+ if (!mappingInterface.featGetter || !mappingInterface.release ||
+ !mappingInterface.dcGetter)
+ {
+ LogError("Failed to obtain mapping interface from .so");
+ ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+ }
+
+ feature_mapping_t* devcapMapping = mappingInterface.featGetter();
+
+ LogDebug("Getting mapping from features to device capabilities");
+
+ for (size_t i = 0; i < devcapMapping->featuresCount; ++i) {
+ PluginMetafileData::Feature feature;
+ feature.m_name = devcapMapping->features[i].feature_name;
+
+ LogDebug("Feature: " << feature.m_name);
+
+ const devcaps_t* dc =
+ mappingInterface.dcGetter(
+ devcapMapping,
+ devcapMapping->features[i].
+ feature_name);
+
+ LogDebug("device=cap: " << dc);
+
+ if (dc) {
+ LogDebug("devcaps count: " << dc->devCapsCount);
+
+ for (size_t j = 0; j < dc->devCapsCount; ++j) {
+ LogDebug("devcap: " << dc->deviceCaps[j]);
+ feature.m_deviceCapabilities.insert(dc->deviceCaps[j]);
+ }
+ }
+
+ m_pluginInfo.m_featureContainer.insert(feature);
+ }
+
+ mappingInterface.release(devcapMapping);
+ }
+
m_libraryObjects = PluginObjectsPtr(new PluginObjects());
- const class_definition_t *rawClassListIterator = rawClassList;
+ const js_entity_definition_t *rawEntityListIterator = rawEntityList;
LogInfo("#####");
LogInfo("##### Plugin: " << filename << " supports new plugin API");
LogInfo("#####");
- while (rawClassListIterator->parent_name != NULL &&
- rawClassListIterator->object_name != NULL &&
- rawClassListIterator->js_class_template != NULL) {
- LogInfo("##### [" << rawClassListIterator->object_name << "]: ");
- LogInfo("##### Parent: " << rawClassListIterator->parent_name);
+ while (rawEntityListIterator->parent_name != NULL &&
+ rawEntityListIterator->object_name != NULL)
+ {
+ LogInfo("##### [" << rawEntityListIterator->object_name << "]: ");
+ LogInfo("##### Parent: " << rawEntityListIterator->parent_name);
LogInfo("#####");
- m_libraryObjects->addObjects(rawClassListIterator->parent_name,
- rawClassListIterator->object_name);
+ m_libraryObjects->addObjects(rawEntityListIterator->parent_name,
+ rawEntityListIterator->object_name);
- ++rawClassListIterator;
-}
+ ++rawEntityListIterator;
+ }
-// Unload library
-if (dlclose(dlHandle) != 0) {
- LogError("Cannot close plugin handle");
-} else {
- LogDebug("Library is unloaded");
-}
+ // Unload library
+ if (dlclose(dlHandle) != 0) {
+ LogError("Cannot close plugin handle");
+ } else {
+ LogDebug("Library is unloaded");
+ }
// Load export table
LogDebug("Library successfuly loaded and parsed");
SET_PLUGIN_INSTALL_PROGRESS(LOADING_LIBRARY, "Library loaded and analyzed");
- //TODO unload library;
}
void PluginInstallTask::stepRegisterPlugin()
LogInfo("Plugin installation: step register Plugin");
m_pluginHandle =
- PluginDAO::registerPlugin(m_pluginMetafile, m_context->pluginFilePath);
+ PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath);
SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered");
}
{
LogInfo("Plugin installation: step register features");
- FOREACH(it, m_pluginMetafile.m_featureContainer)
+ FOREACH(it, m_pluginInfo.m_featureContainer)
{
LogError("PluginHandle: " << m_pluginHandle);
FeatureDAO::RegisterFeature(*it, m_pluginHandle);
{
LogInfo("Plugin installation: step register objects");
+ DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
//register implemented objects
PluginObjects::ObjectsPtr objects =
m_libraryObjects->getImplementedObject();
{
LogInfo("Plugin installation: step resolve dependencies ");
+ //DISABLE_IF_PLUGIN_WITHOUT_LIB
+ if (m_pluginInfo.m_libraryName.empty()) {
+ PluginDAO::setPluginInstallationStatus(
+ m_pluginHandle,
+ PluginDAO::
+ INSTALLATION_COMPLETED);
+ //Installation completed
+ m_context->pluginHandle = m_pluginHandle;
+ m_context->installationCompleted = true;
+ LogWarning("Plugin without library.");
+ return;
+ }
+
PluginHandleSetPtr handles = PluginHandleSetPtr(new PluginHandleSet);
DbPluginHandle handle = INVALID_PLUGIN_HANDLE;