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 <libxml/parser.h>
36 #include <wrt_installer_api.h>
37 #include <installer_callbacks_translate.h>
38 #include <installer_controller.h>
39 #include <language_subtag_rst_tree.h>
40 #include <dpl/localization/localization_utils.h>
41 #include <dpl/wrt-dao-ro/global_config.h>
42 #include <dpl/utils/widget_version.h>
43 #include <dpl/popup/popup_manager.h>
44 #include <dpl/popup/popup_controller.h>
46 #include <dpl/localization/w3c_file_localization.h>
47 #include <dpl/wrt-dao-ro/WrtDatabase.h>
48 #include <vcore/VCore.h>
49 #include <installer_main_thread.h>
51 using namespace WrtDB;
60 #define EXPORT_API __attribute__((visibility("default")))
64 inline WidgetUpdateMode::Type translateWidgetUpdateMode(
65 wrt_widget_update_mode_t updateMode)
67 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 void localizationSetting()
102 char* lang = vconf_get_str(VCONFKEY_LANGSET);
104 LogError("Cannot get locale settings from vconf");
106 LogDebug("Language set to: " << lang);
108 using namespace LocalizationUtils;
110 LanguageTagsList list;
111 list.push_back(DPL::FromUTF8String(lang));
112 SetSystemLanguageTags(list);
114 LogDebug("LanguageChanged to " << lang);
118 const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
119 static int wrt_count_plugin;
121 static std::string cutOffFileName(const std::string& path)
123 size_t found = path.find_last_of("/");
124 if (found == std::string::npos) {
127 return path.substr(0, found);
131 static bool checkPath(const std::string& path)
134 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
137 LogError("Cannot access directory [ " << path << " ]");
141 static bool checkPaths()
144 if_ok &= (checkPath(cutOffFileName(
145 GlobalConfig::GetWrtDatabaseFilePath())));
148 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
149 "> does not exist.");
152 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
155 "Path <" << GlobalConfig::GetDevicePluginPath() <<
156 "> does not exist.");
159 if_ok &= (checkPath(GlobalConfig::GetFactoryInstalledWidgetPath()));
162 "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() <<
163 "> does not exist.");
166 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
169 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
170 "> does not exist.");
175 void plugin_install_status_cb(WrtErrStatus status,
180 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
182 if (--wrt_count_plugin < 1) {
183 LogDebug("All plugins installation completed");
185 LogDebug("Call SetAllinstallpluginsCallback");
186 plugin_data->plugin_installed_cb(plugin_data->user_data);
189 if (status == WRT_SUCCESS) {
191 "plugin installation is successful: " <<
192 plugin_data->plugin_path);
196 LogError("Fail to install plugin : " << plugin_data->plugin_path);
199 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
200 LogError("Failed : Plugin install path is wrong");
202 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
203 LogError("Failed : Plugin Metafile Error");
205 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
206 LogError("Failed : This Plugin is already installed");
208 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
209 LogError("Failed : Library Error. Missing symbol or structures");
211 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
212 LogError("Failed : Waiting for plugin dependencies");
214 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
215 LogError("Failed : Lock Error");
217 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
218 LogError("Failed : Unkown Error");
225 void plugin_install_progress_cb(float percent,
226 const char* description,
229 char *plugin_path = static_cast<char*>(userdata);
231 LogInfo("Install plugin : " << plugin_path <<
232 ", Progress : " << percent <<
233 ", Description : " << description);
236 EXPORT_API int wrt_installer_init(void *userdata,
237 WrtInstallerInitCallback callback)
240 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
244 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
245 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
247 // Touch InstallerController Singleton
248 InstallerMainThreadSingleton::Instance().TouchArchitecture();
253 callback(WRT_ERROR_NO_PATH, userdata);
258 // Initialize ValidationCore - this must be done before AttachDatabases
259 ValidationCore::VCoreInit(
260 std::string(GlobalConfig::GetFingerprintListFile()),
261 std::string(GlobalConfig::GetFingerprintListSchema()),
262 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
264 InstallerMainThreadSingleton::Instance().AttachDatabases();
266 //checking for correct DB version
267 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
268 // LogError("WRONG VERSION OF WRT DATABASE");
269 // Assert(false && "WRONG VERSION OF WRT DATABASE");
272 LogWarning("Database check not implemented!");
274 LogInfo("Prepare libxml2 to work in multithreaded program.");
277 // Initialize Language Subtag registry
278 LanguageSubtagRstTreeSingleton::Instance().Initialize();
279 localizationSetting();
282 CONTROLLER_POST_SYNC_EVENT(
284 InstallerControllerEvents::
287 // Install deferred widget packages
288 CONTROLLER_POST_EVENT(
290 InstallerControllerEvents::
291 InstallDeferredWidgetPackagesEvent());
294 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
295 callback(WRT_SUCCESS, userdata);
298 catch (const DPL::Exception& ex)
300 LogError("Internal Error during Init:");
301 DPL::Exception::DisplayKnownException(ex);
303 callback(WRT_ERROR_INTERNAL, userdata);
311 EXPORT_API void wrt_installer_shutdown()
315 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
317 // Installer termination
318 CONTROLLER_POST_SYNC_EVENT(
320 InstallerControllerEvents::
323 InstallerMainThreadSingleton::Instance().DetachDatabases();
325 // This must be done after DetachDatabase
326 ValidationCore::VCoreDeinit();
328 // Global deinit check
329 LogInfo("Cleanup libxml2 global values.");
333 catch (const DPL::Exception& ex)
335 LogError("Internal Error during Shutdown:");
336 DPL::Exception::DisplayKnownException(ex);
340 EXPORT_API void wrt_install_widget(const char *path,
342 WrtInstallerStatusCallback status_cb,
343 WrtProgressCallback progress_cb,
344 wrt_widget_update_mode_t update_mode,
347 UNHANDLED_EXCEPTION_HANDLER_BEGIN
349 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
350 // Post installation event
351 CONTROLLER_POST_EVENT(
353 InstallerControllerEvents::InstallWidgetEvent(
354 path, WidgetInstallationStruct(
355 InstallerCallbacksTranslate::installFinishedCallback,
356 InstallerCallbacksTranslate::installProgressCallback,
357 new InstallerCallbacksTranslate::StatusCallbackStruct(
358 userdata, status_cb, progress_cb),
359 translateWidgetUpdateMode(update_mode),
362 UNHANDLED_EXCEPTION_HANDLER_END
365 EXPORT_API void wrt_uninstall_widget(int widget_handle,
367 WrtInstallerStatusCallback status_cb,
368 WrtProgressCallback progress_cb)
370 UNHANDLED_EXCEPTION_HANDLER_BEGIN
372 LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle);
373 // Post uninstallation event
374 CONTROLLER_POST_EVENT(
376 InstallerControllerEvents::UninstallWidgetEvent(
378 WidgetUninstallationStruct(
379 InstallerCallbacksTranslate::uninstallFinishedCallback,
380 InstallerCallbacksTranslate::installProgressCallback,
381 new InstallerCallbacksTranslate::StatusCallbackStruct(
382 userdata, status_cb, progress_cb))));
384 UNHANDLED_EXCEPTION_HANDLER_END
387 EXPORT_API void wrt_install_plugin(
388 const char *pluginDir,
390 WrtPluginInstallerStatusCallback status_cb,
391 WrtProgressCallback progress_cb)
393 UNHANDLED_EXCEPTION_HANDLER_BEGIN
395 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
396 //Private data for status callback
397 //Resource is free in pluginInstallFinishedCallback
398 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
400 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
401 user_param, status_cb, progress_cb);
403 CONTROLLER_POST_EVENT(
405 InstallerControllerEvents::InstallPluginEvent(
406 std::string(pluginDir),
407 PluginInstallerStruct(
408 InstallerCallbacksTranslate::
409 pluginInstallFinishedCallback,
410 InstallerCallbacksTranslate::
411 installProgressCallback, callbackStruct)));
413 UNHANDLED_EXCEPTION_HANDLER_END
416 EXPORT_API void wrt_install_all_plugins(
417 WrtAllPluginInstalledCallback installed_cb,
420 UNHANDLED_EXCEPTION_HANDLER_BEGIN
422 std::string installRequest =
423 std::string(GlobalConfig::GetPluginInstallInitializerName());
425 LogDebug("Install new plugins");
428 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
430 Catch(DPL::Semaphore::Exception::Base){
431 LogError("Failed to create installation lock");
437 if (-1 == stat(installRequest.c_str(), &tmp) ||
438 !S_ISREG(tmp.st_mode))
440 if (ENOENT == errno) {
441 LogDebug("Plugin installation not required");
443 LogDebug("Call SetAllinstallPluginCallback");
444 installed_cb(user_param);
446 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
449 LogWarning("Opening installation request file failed");
452 std::string PLUGIN_PATH =
453 std::string(GlobalConfig::GetDevicePluginPath());
456 dir = opendir(PLUGIN_PATH.c_str());
458 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
462 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
463 struct dirent* libdir;
467 std::list<std::string> pluginsPaths;
469 while ((libdir = readdir(dir)) != 0) {
470 if (strcmp(libdir->d_name, ".") == 0 ||
471 strcmp(libdir->d_name, "..") == 0)
476 std::string path = PLUGIN_PATH;
478 path += libdir->d_name;
482 if (stat(path.c_str(), &tmp) == -1) {
483 LogError("Failed to open file" << path);
487 if (!S_ISDIR(tmp.st_mode)) {
488 LogError("Not a directory" << path);
492 pluginsPaths.push_back(path);
495 wrt_count_plugin = pluginsPaths.size();
497 FOREACH(it, pluginsPaths) {
498 wrt_plugin_data *plugin_data = new wrt_plugin_data;
500 plugin_data->plugin_installed_cb = installed_cb;
501 plugin_data->plugin_path = const_cast<char*>(it->c_str());
502 plugin_data->user_data = user_param;
505 it->c_str(), static_cast<void*>(plugin_data),
506 plugin_install_status_cb,
507 plugin_install_progress_cb);
510 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
511 LogError("Failed to close dir: " << dir);
514 if (0 != unlink(installRequest.c_str())) {
515 LogError("Failed to remove file initializing plugin "
520 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
522 Catch(DPL::Semaphore::Exception::Base){
523 LogInfo("Failed to remove installation lock");
526 UNHANDLED_EXCEPTION_HANDLER_END
529 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
530 WrtInstallerInitCallback callback)
533 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
537 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
538 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
540 // Touch InstallerController Singleton
541 InstallerMainThreadSingleton::Instance().
542 TouchArchitectureOnlyInstaller();
547 callback(WRT_ERROR_NO_PATH, userdata);
552 CONTROLLER_POST_SYNC_EVENT(
554 InstallerControllerEvents::
558 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
559 callback(WRT_SUCCESS, userdata);
562 catch (const DPL::Exception& ex)
564 LogError("Internal Error during Init:");
565 DPL::Exception::DisplayKnownException(ex);
567 callback(WRT_ERROR_INTERNAL, userdata);
576 EXPORT_API void wrt_installer_shutdown_for_tests()
580 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
582 // Installer termination
583 CONTROLLER_POST_SYNC_EVENT(
585 InstallerControllerEvents::
588 // Global deinit check
589 LogInfo("Cleanup libxml2 global values.");
592 catch (const DPL::Exception& ex)
594 LogError("Internal Error during Shutdown:");
595 DPL::Exception::DisplayKnownException(ex);
599 EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname,
604 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : "
607 WidgetHandle handle = WidgetDAOReadOnly::getHandle(
608 DPL::FromASCIIString(pkgname));
609 *widget_handle = static_cast<int>(handle);
612 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
614 LogError("Error package name is not found");
615 return WRT_ERROR_PKGNAME_NOT_FOUND;
617 catch (const DPL::Exception& ex)
619 LogError("Internal Error during get widget id by package name");
620 DPL::Exception::DisplayKnownException(ex);
621 return WRT_ERROR_INTERNAL;
625 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid,
630 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : "
633 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
634 WidgetHandle handle = WidgetDAOReadOnly::getHandle(widget_guid);
635 *widget_handle = static_cast<int>(handle);
638 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
640 LogError("Error package name is not found");
641 return WRT_ERROR_PKGNAME_NOT_FOUND;
643 catch (const DPL::Exception& ex)
645 LogError("Internal Error during get widget id by package name");
646 DPL::Exception::DisplayKnownException(ex);
647 return WRT_ERROR_INTERNAL;