2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file install_one_task.cpp
18 * @author Pawel Sikorski (p.sikorski@samgsung.com)
19 * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com)
25 #include <sys/types.h>
30 #include <dpl/log/log.h>
31 #include <dpl/foreach.h>
33 #include "plugin_install_task.h"
34 #include "job_plugin_install.h"
35 #include "plugin_installer_errors.h"
36 #include "plugin_metafile_reader.h"
37 #include <dpl/wrt-dao-ro/global_config.h>
39 #include <wrt_common_types.h>
40 #include <dpl/wrt-dao-rw/feature_dao.h>
41 #include <dpl/wrt-dao-rw/plugin_dao.h>
42 #include "plugin_objects.h"
44 using namespace WrtDB;
47 const std::string DIRECTORY_SEPARATOR = std::string("/");
50 #define SET_PLUGIN_INSTALL_PROGRESS(step, desc) \
51 m_context->installerTask->UpdateProgress( \
52 PluginInstallerContext::step, desc);
54 #define DISABLE_IF_PLUGIN_WITHOUT_LIB() \
55 if(m_pluginMetafile.m_libraryName.empty()) \
57 LogWarning("Plugin without library."); \
62 namespace PluginInstall {
63 PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) :
64 DPL::TaskDecl<PluginInstallTask>(this),
67 AddStep(&PluginInstallTask::stepCheckPluginPath);
68 AddStep(&PluginInstallTask::stepParseConfigFile);
69 AddStep(&PluginInstallTask::stepCheckIfAlreadyInstalled);
70 AddStep(&PluginInstallTask::stepLoadPluginLibrary);
71 AddStep(&PluginInstallTask::stepRegisterPlugin);
72 AddStep(&PluginInstallTask::stepRegisterFeatures);
73 AddStep(&PluginInstallTask::stepRegisterPluginObjects);
74 AddStep(&PluginInstallTask::stepResolvePluginDependencies);
76 SET_PLUGIN_INSTALL_PROGRESS(START, "Installation initialized");
79 PluginInstallTask::~PluginInstallTask()
83 void PluginInstallTask::stepCheckPluginPath()
85 LogInfo("Plugin installation: step CheckPluginPath");
89 if (-1 == stat(m_context->pluginFilePath.c_str(), &tmp)) {
90 ThrowMsg(Exceptions::PluginPathFailed,
91 "Stat function failed");
94 if (!S_ISDIR(tmp.st_mode)) {
95 ThrowMsg(Exceptions::PluginPathFailed,
99 SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified");
102 void PluginInstallTask::stepParseConfigFile()
104 LogInfo("Plugin installation: step parse config file");
106 std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
107 std::string(GlobalConfig::GetPluginMetafileName());
109 LogInfo("Plugin Config file::" << filename);
113 PluginMetafileReader reader;
114 reader.initialize(filename);
115 reader.read(m_pluginMetafile);
117 FOREACH(it, m_pluginMetafile.m_featureContainer)
119 LogDebug("Parsed feature : " << it->m_name);
120 FOREACH (devCap, it->m_deviceCapabilities) {
121 LogDebug(" | DevCap : " << *devCap);
125 SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Config file analyzed");
127 Catch(ValidationCore::ParserSchemaException::Base)
129 LogError("Error during file processing " << filename);
130 ThrowMsg(Exceptions::PluginMetafileFailed,
135 void PluginInstallTask::stepCheckIfAlreadyInstalled()
137 if (PluginDAO::isPluginInstalled(m_pluginMetafile.m_libraryName)) {
138 ThrowMsg(Exceptions::PluginAlreadyInstalled,
139 "Plugin already installed");
142 SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_EXISTS_CHECK, "Check if plugin exist");
145 void PluginInstallTask::stepLoadPluginLibrary()
147 LogInfo("Plugin installation: step load library");
149 DISABLE_IF_PLUGIN_WITHOUT_LIB()
151 std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR +
152 m_pluginMetafile.m_libraryName;
154 LogDebug("Loading plugin: " << filename);
156 void *dlHandle = dlopen(filename.c_str(), RTLD_LAZY);
157 if (dlHandle == NULL ) {
159 "Failed to load plugin: " << filename <<
160 ". Reason: " << dlerror());
161 ThrowMsg(Exceptions::PluginLibraryError, "Library error");
164 const class_definition_t *rawClassList = NULL;
165 get_widget_class_map_proc *getWidgetClassMapProcPtr = NULL;
167 getWidgetClassMapProcPtr =
168 reinterpret_cast<get_widget_class_map_proc *>(dlsym(dlHandle,
169 PLUGIN_GET_CLASS_MAP_PROC_NAME));
171 if (getWidgetClassMapProcPtr) {
172 rawClassList = (*getWidgetClassMapProcPtr)();
175 static_cast<const class_definition_t *>(dlsym(dlHandle,
176 PLUGIN_CLASS_MAP_NAME));
179 if (rawClassList == NULL) {
181 LogError("Failed to read class name" << filename);
182 ThrowMsg(Exceptions::PluginLibraryError, "Library error");
185 m_libraryObjects = PluginObjectsPtr(new PluginObjects());
186 const class_definition_t *rawClassListIterator = rawClassList;
189 LogInfo("##### Plugin: " << filename << " supports new plugin API");
192 while (rawClassListIterator->parent_name != NULL &&
193 rawClassListIterator->object_name != NULL &&
194 rawClassListIterator->js_class_template != NULL) {
195 LogInfo("##### [" << rawClassListIterator->object_name << "]: ");
196 LogInfo("##### Parent: " << rawClassListIterator->parent_name);
199 m_libraryObjects->addObjects(rawClassListIterator->parent_name,
200 rawClassListIterator->object_name);
202 ++rawClassListIterator;
206 if (dlclose(dlHandle) != 0) {
207 LogError("Cannot close plugin handle");
209 LogDebug("Library is unloaded");
213 LogDebug("Library successfuly loaded and parsed");
215 SET_PLUGIN_INSTALL_PROGRESS(LOADING_LIBRARY, "Library loaded and analyzed");
216 //TODO unload library;
219 void PluginInstallTask::stepRegisterPlugin()
221 LogInfo("Plugin installation: step register Plugin");
224 PluginDAO::registerPlugin(m_pluginMetafile, m_context->pluginFilePath);
226 SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered");
229 void PluginInstallTask::stepRegisterFeatures()
231 LogInfo("Plugin installation: step register features");
233 FOREACH(it, m_pluginMetafile.m_featureContainer)
235 LogError("PluginHandle: " << m_pluginHandle);
236 FeatureDAO::RegisterFeature(*it, m_pluginHandle);
238 SET_PLUGIN_INSTALL_PROGRESS(REGISTER_FEATURES, "Features registered");
241 void PluginInstallTask::stepRegisterPluginObjects()
243 LogInfo("Plugin installation: step register objects");
245 DISABLE_IF_PLUGIN_WITHOUT_LIB()
247 //register implemented objects
248 PluginObjects::ObjectsPtr objects =
249 m_libraryObjects->getImplementedObject();
251 FOREACH(it, *objects)
253 PluginDAO::registerPluginImplementedObject(*it, m_pluginHandle);
256 //register requiredObjects
257 objects = m_libraryObjects->getDependentObjects();
259 FOREACH(it, *objects)
261 if (m_libraryObjects->hasObject(*it)) {
262 LogDebug("Dependency from the same library. ignored");
266 PluginDAO::registerPluginRequiredObject(*it, m_pluginHandle);
269 SET_PLUGIN_INSTALL_PROGRESS(REGISTER_OBJECTS, "Plugin Objects registered");
272 void PluginInstallTask::stepResolvePluginDependencies()
274 LogInfo("Plugin installation: step resolve dependencies ");
276 //DISABLE_IF_PLUGIN_WITHOUT_LIB
277 if(m_pluginMetafile.m_libraryName.empty())
279 PluginDAO::setPluginInstallationStatus(m_pluginHandle,
280 PluginDAO::INSTALLATION_COMPLETED);
281 //Installation completed
282 m_context->pluginHandle = m_pluginHandle;
283 m_context->installationCompleted = true;
284 LogWarning("Plugin without library.");
288 PluginHandleSetPtr handles = PluginHandleSetPtr(new PluginHandleSet);
290 DbPluginHandle handle = INVALID_PLUGIN_HANDLE;
292 //register requiredObjects
293 FOREACH(it, *(m_libraryObjects->getDependentObjects()))
295 if (m_libraryObjects->hasObject(*it)) {
296 LogDebug("Dependency from the same library. ignored");
300 handle = PluginDAO::getPluginHandleForImplementedObject(*it);
301 if (handle == INVALID_PLUGIN_HANDLE) {
302 LogError("Library implementing: " << *it << " NOT FOUND");
303 PluginDAO::setPluginInstallationStatus(
305 PluginDAO::INSTALLATION_WAITING);
309 handles->insert(handle);
312 PluginDAO::registerPluginLibrariesDependencies(m_pluginHandle, handles);
314 PluginDAO::setPluginInstallationStatus(m_pluginHandle,
315 PluginDAO::INSTALLATION_COMPLETED);
317 //Installation completed
318 m_context->pluginHandle = m_pluginHandle;
319 m_context->installationCompleted = true;
321 SET_PLUGIN_INSTALL_PROGRESS(RESOLVE_DEPENDENCIES, "Dependencies resolved");
324 #undef SET_PLUGIN_INSTALL_PROGRESS
326 } //namespace PluginInstall