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 wrt_installer_api.cpp
18 * @author Chung Jihoon (jihoon.chung@samsung.com)
20 * @brief This file contains definitions of wrt installer api
25 #include <sys/types.h>
28 #include <dpl/exception.h>
29 #include <dpl/log/log.h>
30 #include <dpl/assert.h>
31 #include <dpl/semaphore.h>
32 #include <dpl/sstream.h>
33 #include <dpl/errno_string.h>
34 #include <libxml/parser.h>
37 #include <wrt_installer_api.h>
38 #include <installer_callbacks_translate.h>
39 #include <installer_controller.h>
40 #include <language_subtag_rst_tree.h>
41 #include <dpl/wrt-dao-ro/global_config.h>
42 #include <dpl/utils/widget_version.h>
44 #include <dpl/localization/w3c_file_localization.h>
45 #include <dpl/wrt-dao-ro/WrtDatabase.h>
46 #include <vcore/VCore.h>
47 #include <installer_main_thread.h>
49 using namespace WrtDB;
58 #define EXPORT_API __attribute__((visibility("default")))
62 inline WidgetUpdateMode::Type translateWidgetUpdateMode(
63 wrt_widget_update_mode_t updateMode)
65 if (updateMode == WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL)
66 return WidgetUpdateMode::PolicyDirectoryForceInstall;
68 WidgetUpdateMode::Type result = WidgetUpdateMode::Zero;
69 if (updateMode & WRT_WIM_NOT_INSTALLED) {
70 result = result | WidgetUpdateMode::NotInstalled;
73 if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) {
74 result = result | WidgetUpdateMode::IncomingVersionNotStd;
77 if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) {
78 result = result | WidgetUpdateMode::ExistingVersionNotStd;
81 if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) {
82 result = result | WidgetUpdateMode::BothVersionsNotStd;
85 if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) {
86 result = result | WidgetUpdateMode::ExistingVersionOlder;
89 if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) {
90 result = result | WidgetUpdateMode::ExistingVersionEqual;
93 if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) {
94 result = result | WidgetUpdateMode::ExistingVersionNewer;
100 const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
101 static int wrt_count_plugin;
103 static std::string cutOffFileName(const std::string& path)
105 size_t found = path.find_last_of("/");
106 if (found == std::string::npos) {
109 return path.substr(0, found);
113 static bool checkPath(const std::string& path)
116 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
119 LogError("Cannot access directory [ " << path << " ]");
123 static bool checkPaths()
126 if_ok &= (checkPath(cutOffFileName(
127 GlobalConfig::GetWrtDatabaseFilePath())));
130 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
131 "> does not exist.");
134 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
137 "Path <" << GlobalConfig::GetDevicePluginPath() <<
138 "> does not exist.");
141 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
144 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
145 "> does not exist.");
150 void plugin_install_status_cb(WrtErrStatus status,
155 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
157 if (--wrt_count_plugin < 1) {
158 LogDebug("All plugins installation completed");
160 LogDebug("Call SetAllinstallpluginsCallback");
161 plugin_data->plugin_installed_cb(plugin_data->user_data);
164 if (status == WRT_SUCCESS) {
166 "plugin installation is successful: " <<
167 plugin_data->plugin_path);
171 LogError("Fail to install plugin : " << plugin_data->plugin_path);
174 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
175 LogError("Failed : Plugin install path is wrong");
177 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
178 LogError("Failed : Plugin Metafile Error");
180 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
181 LogError("Failed : This Plugin is already installed");
183 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
184 LogError("Failed : Library Error. Missing symbol or structures");
186 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
187 LogError("Failed : Waiting for plugin dependencies");
189 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
190 LogError("Failed : Lock Error");
192 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
193 LogError("Failed : Unkown Error");
200 void plugin_install_progress_cb(float percent,
201 const char* description,
204 char *plugin_path = static_cast<char*>(userdata);
206 LogInfo("Install plugin : " << plugin_path <<
207 ", Progress : " << percent <<
208 ", Description : " << description);
211 EXPORT_API int wrt_installer_init(void *userdata,
212 WrtInstallerInitCallback callback)
215 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
219 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
220 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
222 // Touch InstallerController Singleton
223 InstallerMainThreadSingleton::Instance().TouchArchitecture();
228 callback(WRT_ERROR_NO_PATH, userdata);
233 // Initialize ValidationCore - this must be done before AttachDatabases
234 ValidationCore::VCoreInit(
235 std::string(GlobalConfig::GetFingerprintListFile()),
236 std::string(GlobalConfig::GetFingerprintListSchema()),
237 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
239 InstallerMainThreadSingleton::Instance().AttachDatabases();
241 //checking for correct DB version
242 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
243 // LogError("WRONG VERSION OF WRT DATABASE");
244 // Assert(false && "WRONG VERSION OF WRT DATABASE");
247 LogWarning("Database check not implemented!");
249 LogInfo("Prepare libxml2 to work in multithreaded program.");
252 // Initialize Language Subtag registry
253 LanguageSubtagRstTreeSingleton::Instance().Initialize();
256 CONTROLLER_POST_SYNC_EVENT(
257 Logic::InstallerController,
258 InstallerControllerEvents::
261 // Install deferred widget packages
262 CONTROLLER_POST_EVENT(
263 Logic::InstallerController,
264 InstallerControllerEvents::
265 InstallDeferredWidgetPackagesEvent());
268 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
269 callback(WRT_SUCCESS, userdata);
272 catch (const DPL::Exception& ex)
274 LogError("Internal Error during Init:");
275 DPL::Exception::DisplayKnownException(ex);
277 callback(WRT_ERROR_INTERNAL, userdata);
285 EXPORT_API void wrt_installer_shutdown()
289 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
291 // Installer termination
292 CONTROLLER_POST_SYNC_EVENT(
293 Logic::InstallerController,
294 InstallerControllerEvents::
297 InstallerMainThreadSingleton::Instance().DetachDatabases();
299 // This must be done after DetachDatabase
300 ValidationCore::VCoreDeinit();
302 // Global deinit check
303 LogInfo("Cleanup libxml2 global values.");
307 catch (const DPL::Exception& ex)
309 LogError("Internal Error during Shutdown:");
310 DPL::Exception::DisplayKnownException(ex);
314 EXPORT_API void wrt_install_widget(const char *path,
316 WrtInstallerStatusCallback status_cb,
317 WrtProgressCallback progress_cb,
318 wrt_widget_update_mode_t update_mode,
321 UNHANDLED_EXCEPTION_HANDLER_BEGIN
323 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
324 // Post installation event
325 CONTROLLER_POST_EVENT(
326 Logic::InstallerController,
327 InstallerControllerEvents::InstallWidgetEvent(
328 path, WidgetInstallationStruct(
329 InstallerCallbacksTranslate::installFinishedCallback,
330 InstallerCallbacksTranslate::installProgressCallback,
331 new InstallerCallbacksTranslate::StatusCallbackStruct(
332 userdata, status_cb, progress_cb),
333 translateWidgetUpdateMode(update_mode),
336 UNHANDLED_EXCEPTION_HANDLER_END
339 EXPORT_API void wrt_uninstall_widget(const char * const pkg_name,
341 WrtInstallerStatusCallback status_cb,
342 WrtProgressCallback progress_cb)
344 UNHANDLED_EXCEPTION_HANDLER_BEGIN
346 std::string widgetPkgName(pkg_name);
347 LogInfo("[WRT-API] UNINSTALL WIDGET: " << widgetPkgName);
348 // Post uninstallation event
349 CONTROLLER_POST_EVENT(
350 Logic::InstallerController,
351 InstallerControllerEvents::UninstallWidgetEvent(
353 WidgetUninstallationStruct(
354 InstallerCallbacksTranslate::uninstallFinishedCallback,
355 InstallerCallbacksTranslate::installProgressCallback,
356 new InstallerCallbacksTranslate::StatusCallbackStruct(
357 userdata, status_cb, progress_cb))));
359 UNHANDLED_EXCEPTION_HANDLER_END
362 EXPORT_API void wrt_install_plugin(
363 const char *pluginDir,
365 WrtPluginInstallerStatusCallback status_cb,
366 WrtProgressCallback progress_cb)
368 UNHANDLED_EXCEPTION_HANDLER_BEGIN
370 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
371 //Private data for status callback
372 //Resource is free in pluginInstallFinishedCallback
373 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
375 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
376 user_param, status_cb, progress_cb);
378 CONTROLLER_POST_EVENT(
379 Logic::InstallerController,
380 InstallerControllerEvents::InstallPluginEvent(
381 std::string(pluginDir),
382 PluginInstallerStruct(
383 InstallerCallbacksTranslate::
384 pluginInstallFinishedCallback,
385 InstallerCallbacksTranslate::
386 installProgressCallback, callbackStruct)));
388 UNHANDLED_EXCEPTION_HANDLER_END
391 EXPORT_API void wrt_install_all_plugins(
392 WrtAllPluginInstalledCallback installed_cb,
395 UNHANDLED_EXCEPTION_HANDLER_BEGIN
397 std::string installRequest =
398 std::string(GlobalConfig::GetPluginInstallInitializerName());
400 LogDebug("Install new plugins");
403 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
405 Catch(DPL::Semaphore::Exception::Base){
406 LogError("Failed to create installation lock");
412 if (-1 == stat(installRequest.c_str(), &tmp) ||
413 !S_ISREG(tmp.st_mode))
415 if (ENOENT == errno) {
416 LogDebug("Plugin installation not required");
418 LogDebug("Call SetAllinstallPluginCallback");
419 installed_cb(user_param);
421 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
424 LogWarning("Opening installation request file failed");
427 std::string PLUGIN_PATH =
428 std::string(GlobalConfig::GetDevicePluginPath());
431 dir = opendir(PLUGIN_PATH.c_str());
433 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
437 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
438 struct dirent* libdir;
442 std::list<std::string> pluginsPaths;
444 while ((libdir = readdir(dir)) != 0) {
445 if (strcmp(libdir->d_name, ".") == 0 ||
446 strcmp(libdir->d_name, "..") == 0)
451 std::string path = PLUGIN_PATH;
453 path += libdir->d_name;
457 if (stat(path.c_str(), &tmp) == -1) {
458 LogError("Failed to open file" << path);
462 if (!S_ISDIR(tmp.st_mode)) {
463 LogError("Not a directory" << path);
467 pluginsPaths.push_back(path);
470 wrt_count_plugin = pluginsPaths.size();
472 FOREACH(it, pluginsPaths) {
473 wrt_plugin_data *plugin_data = new wrt_plugin_data;
475 plugin_data->plugin_installed_cb = installed_cb;
476 plugin_data->plugin_path = const_cast<char*>(it->c_str());
477 plugin_data->user_data = user_param;
480 it->c_str(), static_cast<void*>(plugin_data),
481 plugin_install_status_cb,
482 plugin_install_progress_cb);
485 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
486 LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
487 << DPL::GetErrnoString());
490 if (0 != unlink(installRequest.c_str())) {
491 LogError("Failed to remove file initializing plugin "
496 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
498 Catch(DPL::Semaphore::Exception::Base){
499 LogInfo("Failed to remove installation lock");
502 UNHANDLED_EXCEPTION_HANDLER_END
505 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
506 WrtInstallerInitCallback callback)
509 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
513 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
514 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
516 // Touch InstallerController Singleton
517 InstallerMainThreadSingleton::Instance().
518 TouchArchitectureOnlyInstaller();
523 callback(WRT_ERROR_NO_PATH, userdata);
528 CONTROLLER_POST_SYNC_EVENT(
529 Logic::InstallerController,
530 InstallerControllerEvents::
534 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
535 callback(WRT_SUCCESS, userdata);
538 catch (const DPL::Exception& ex)
540 LogError("Internal Error during Init:");
541 DPL::Exception::DisplayKnownException(ex);
543 callback(WRT_ERROR_INTERNAL, userdata);
552 EXPORT_API void wrt_installer_shutdown_for_tests()
556 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
558 // Installer termination
559 CONTROLLER_POST_SYNC_EVENT(
560 Logic::InstallerController,
561 InstallerControllerEvents::
564 // Global deinit check
565 LogInfo("Cleanup libxml2 global values.");
568 catch (const DPL::Exception& ex)
570 LogError("Internal Error during Shutdown:");
571 DPL::Exception::DisplayKnownException(ex);
575 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(std::string & pkgname,
576 const std::string guid)
580 LogInfo("[WRT-API] GETTING WIDGET PACKAGE NAME BY WidgetID : "
583 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
584 WrtDB::WidgetDAOReadOnly dao(widget_guid);
585 pkgname = DPL::ToUTF8String(*dao.getPkgname());
588 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
590 LogError("Error package name is not found");
591 return WRT_ERROR_PKGNAME_NOT_FOUND;
593 catch (const DPL::Exception& ex)
595 LogError("Internal Error during get widget id by package name");
596 DPL::Exception::DisplayKnownException(ex);
597 return WRT_ERROR_INTERNAL;