X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fjobs%2Fplugin_install%2Fplugin_install_task.cpp;h=65333bae94d1f6ca1a221c90bca21815fa8d387f;hb=59676b6982ae51a22fcea3e7de950864cd22139d;hp=218e10b0fb14a2856ccf988c8f4d1785b87b3928;hpb=615ac89e41f56c38e75ecb6e243480b87698c114;p=framework%2Fweb%2Fwrt-installer.git diff --git a/src/jobs/plugin_install/plugin_install_task.cpp b/src/jobs/plugin_install/plugin_install_task.cpp index 218e10b..65333ba 100644 --- a/src/jobs/plugin_install/plugin_install_task.cpp +++ b/src/jobs/plugin_install/plugin_install_task.cpp @@ -28,6 +28,7 @@ //WRT INCLUDES #include +#include #include #include "plugin_install_task.h" #include "job_plugin_install.h" @@ -39,6 +40,7 @@ #include #include #include "plugin_objects.h" +#include using namespace WrtDB; @@ -50,14 +52,24 @@ const std::string DIRECTORY_SEPARATOR = std::string("/"); 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(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); @@ -69,8 +81,7 @@ PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) : } PluginInstallTask::~PluginInstallTask() -{ -} +{} void PluginInstallTask::stepCheckPluginPath() { @@ -95,16 +106,31 @@ 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_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"); } @@ -116,9 +142,31 @@ 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"); } @@ -130,72 +178,129 @@ void PluginInstallTask::stepLoadPluginLibrary() { 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(dlsym(dlHandle, - PLUGIN_GET_CLASS_MAP_PROC_NAME)); + getWidgetEntityMapProcPtr = + reinterpret_cast(dlsym(dlHandle, + PLUGIN_GET_CLASS_MAP_PROC_NAME)); - if (getWidgetClassMapProcPtr) { - rawClassList = (*getWidgetClassMapProcPtr)(); + if (getWidgetEntityMapProcPtr) { + rawEntityList = (*getWidgetEntityMapProcPtr)(); } else { - rawClassList = - static_cast(dlsym(dlHandle, - PLUGIN_CLASS_MAP_NAME)); + rawEntityList = + static_cast(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( + 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() @@ -203,7 +308,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"); } @@ -212,7 +317,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); @@ -224,6 +329,8 @@ void PluginInstallTask::stepRegisterPluginObjects() { LogInfo("Plugin installation: step register objects"); + DISABLE_IF_PLUGIN_WITHOUT_LIB() + //register implemented objects PluginObjects::ObjectsPtr objects = m_libraryObjects->getImplementedObject(); @@ -253,6 +360,19 @@ void PluginInstallTask::stepResolvePluginDependencies() { 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;