Update wrt-installer_0.0.51
[framework/web/wrt-installer.git] / src / jobs / plugin_install / plugin_install_task.cpp
index 0d7f147..57d3c0c 100644 (file)
@@ -40,6 +40,7 @@
 #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;
 
@@ -52,7 +53,7 @@ const std::string DIRECTORY_SEPARATOR = std::string("/");
         PluginInstallerContext::step, desc);
 
 #define DISABLE_IF_PLUGIN_WITHOUT_LIB()        \
-    if(m_pluginMetafile.m_libraryName.empty()) \
+    if(m_pluginInfo.m_libraryName.empty()) \
     {                                          \
         LogWarning("Plugin without library."); \
         return;                                \
@@ -60,12 +61,15 @@ const std::string DIRECTORY_SEPARATOR = std::string("/");
 
 namespace Jobs {
 namespace PluginInstall {
+
 PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) :
     DPL::TaskDecl<PluginInstallTask>(this),
-    m_context(inCont)
+    m_context(inCont),
+    m_dataFromConfigXML(true)
 {
     AddStep(&PluginInstallTask::stepCheckPluginPath);
     AddStep(&PluginInstallTask::stepParseConfigFile);
+    AddStep(&PluginInstallTask::stepFindPluginLibrary);
     AddStep(&PluginInstallTask::stepCheckIfAlreadyInstalled);
     AddStep(&PluginInstallTask::stepLoadPluginLibrary);
     AddStep(&PluginInstallTask::stepRegisterPlugin);
@@ -103,18 +107,25 @@ void PluginInstallTask::stepParseConfigFile()
 {
     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_pluginMetafile.m_featureContainer)
+        FOREACH(it, m_pluginInfo.m_featureContainer)
         {
             LogDebug("Parsed feature : " << it->m_name);
             FOREACH (devCap, it->m_deviceCapabilities) {
@@ -132,9 +143,34 @@ void PluginInstallTask::stepParseConfigFile()
     }
 }
 
+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");
     }
@@ -149,11 +185,11 @@ void PluginInstallTask::stepLoadPluginLibrary()
     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);
+    void *dlHandle = dlopen(filename.c_str(), RTLD_NOW);
     if (dlHandle == NULL ) {
         LogError(
                 "Failed to load plugin: " << filename <<
@@ -161,59 +197,116 @@ void PluginInstallTask::stepLoadPluginLibrary()
         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,
+    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,
+        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()
@@ -221,7 +314,7 @@ 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");
 }
@@ -230,7 +323,7 @@ void PluginInstallTask::stepRegisterFeatures()
 {
     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);
@@ -274,7 +367,7 @@ void PluginInstallTask::stepResolvePluginDependencies()
     LogInfo("Plugin installation: step resolve dependencies ");
 
     //DISABLE_IF_PLUGIN_WITHOUT_LIB
-    if(m_pluginMetafile.m_libraryName.empty())
+    if(m_pluginInfo.m_libraryName.empty())
     {
         PluginDAO::setPluginInstallationStatus(m_pluginHandle,
                                            PluginDAO::INSTALLATION_COMPLETED);