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/wrt-dao-ro/global_config.h>
41 #include <dpl/utils/widget_version.h>
43 #include <dpl/localization/w3c_file_localization.h>
44 #include <dpl/wrt-dao-ro/WrtDatabase.h>
45 #include <vcore/VCore.h>
46 #include <installer_main_thread.h>
48 using namespace WrtDB;
57 #define EXPORT_API __attribute__((visibility("default")))
61 inline WidgetUpdateMode::Type translateWidgetUpdateMode(
62 wrt_widget_update_mode_t updateMode)
64 WidgetUpdateMode::Type result = WidgetUpdateMode::Zero;
66 if (updateMode & WRT_WIM_NOT_INSTALLED) {
67 result = result | WidgetUpdateMode::NotInstalled;
70 if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) {
71 result = result | WidgetUpdateMode::IncomingVersionNotStd;
74 if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) {
75 result = result | WidgetUpdateMode::ExistingVersionNotStd;
78 if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) {
79 result = result | WidgetUpdateMode::BothVersionsNotStd;
82 if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) {
83 result = result | WidgetUpdateMode::ExistingVersionOlder;
86 if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) {
87 result = result | WidgetUpdateMode::ExistingVersionEqual;
90 if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) {
91 result = result | WidgetUpdateMode::ExistingVersionNewer;
97 const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
98 static int wrt_count_plugin;
100 static std::string cutOffFileName(const std::string& path)
102 size_t found = path.find_last_of("/");
103 if (found == std::string::npos) {
106 return path.substr(0, found);
110 static bool checkPath(const std::string& path)
113 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
116 LogError("Cannot access directory [ " << path << " ]");
120 static bool checkPaths()
123 if_ok &= (checkPath(cutOffFileName(
124 GlobalConfig::GetWrtDatabaseFilePath())));
127 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
128 "> does not exist.");
131 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
134 "Path <" << GlobalConfig::GetDevicePluginPath() <<
135 "> does not exist.");
138 if_ok &= (checkPath(GlobalConfig::GetFactoryInstalledWidgetPath()));
141 "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() <<
142 "> does not exist.");
145 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
148 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
149 "> does not exist.");
154 void plugin_install_status_cb(WrtErrStatus status,
159 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
161 if (--wrt_count_plugin < 1) {
162 LogDebug("All plugins installation completed");
164 LogDebug("Call SetAllinstallpluginsCallback");
165 plugin_data->plugin_installed_cb(plugin_data->user_data);
168 if (status == WRT_SUCCESS) {
170 "plugin installation is successful: " <<
171 plugin_data->plugin_path);
175 LogError("Fail to install plugin : " << plugin_data->plugin_path);
178 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
179 LogError("Failed : Plugin install path is wrong");
181 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
182 LogError("Failed : Plugin Metafile Error");
184 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
185 LogError("Failed : This Plugin is already installed");
187 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
188 LogError("Failed : Library Error. Missing symbol or structures");
190 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
191 LogError("Failed : Waiting for plugin dependencies");
193 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
194 LogError("Failed : Lock Error");
196 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
197 LogError("Failed : Unkown Error");
204 void plugin_install_progress_cb(float percent,
205 const char* description,
208 char *plugin_path = static_cast<char*>(userdata);
210 LogInfo("Install plugin : " << plugin_path <<
211 ", Progress : " << percent <<
212 ", Description : " << description);
215 EXPORT_API int wrt_installer_init(void *userdata,
216 WrtInstallerInitCallback callback)
219 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
223 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
224 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
226 // Touch InstallerController Singleton
227 InstallerMainThreadSingleton::Instance().TouchArchitecture();
232 callback(WRT_ERROR_NO_PATH, userdata);
237 // Initialize ValidationCore - this must be done before AttachDatabases
238 ValidationCore::VCoreInit(
239 std::string(GlobalConfig::GetFingerprintListFile()),
240 std::string(GlobalConfig::GetFingerprintListSchema()),
241 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
243 InstallerMainThreadSingleton::Instance().AttachDatabases();
245 //checking for correct DB version
246 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
247 // LogError("WRONG VERSION OF WRT DATABASE");
248 // Assert(false && "WRONG VERSION OF WRT DATABASE");
251 LogWarning("Database check not implemented!");
253 LogInfo("Prepare libxml2 to work in multithreaded program.");
256 // Initialize Language Subtag registry
257 LanguageSubtagRstTreeSingleton::Instance().Initialize();
260 CONTROLLER_POST_SYNC_EVENT(
261 Logic::InstallerController,
262 InstallerControllerEvents::
265 // Install deferred widget packages
266 CONTROLLER_POST_EVENT(
267 Logic::InstallerController,
268 InstallerControllerEvents::
269 InstallDeferredWidgetPackagesEvent());
272 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
273 callback(WRT_SUCCESS, userdata);
276 catch (const DPL::Exception& ex)
278 LogError("Internal Error during Init:");
279 DPL::Exception::DisplayKnownException(ex);
281 callback(WRT_ERROR_INTERNAL, userdata);
289 EXPORT_API void wrt_installer_shutdown()
293 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
295 // Installer termination
296 CONTROLLER_POST_SYNC_EVENT(
297 Logic::InstallerController,
298 InstallerControllerEvents::
301 InstallerMainThreadSingleton::Instance().DetachDatabases();
303 // This must be done after DetachDatabase
304 ValidationCore::VCoreDeinit();
306 // Global deinit check
307 LogInfo("Cleanup libxml2 global values.");
311 catch (const DPL::Exception& ex)
313 LogError("Internal Error during Shutdown:");
314 DPL::Exception::DisplayKnownException(ex);
318 EXPORT_API void wrt_install_widget(const char *path,
320 WrtInstallerStatusCallback status_cb,
321 WrtProgressCallback progress_cb,
322 wrt_widget_update_mode_t update_mode,
325 UNHANDLED_EXCEPTION_HANDLER_BEGIN
327 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
328 // Post installation event
329 CONTROLLER_POST_EVENT(
330 Logic::InstallerController,
331 InstallerControllerEvents::InstallWidgetEvent(
332 path, WidgetInstallationStruct(
333 InstallerCallbacksTranslate::installFinishedCallback,
334 InstallerCallbacksTranslate::installProgressCallback,
335 new InstallerCallbacksTranslate::StatusCallbackStruct(
336 userdata, status_cb, progress_cb),
337 translateWidgetUpdateMode(update_mode),
340 UNHANDLED_EXCEPTION_HANDLER_END
343 EXPORT_API void wrt_uninstall_widget(int widget_handle,
345 WrtInstallerStatusCallback status_cb,
346 WrtProgressCallback progress_cb)
348 UNHANDLED_EXCEPTION_HANDLER_BEGIN
350 LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle);
351 // Post uninstallation event
352 CONTROLLER_POST_EVENT(
353 Logic::InstallerController,
354 InstallerControllerEvents::UninstallWidgetEvent(
356 WidgetUninstallationStruct(
357 InstallerCallbacksTranslate::uninstallFinishedCallback,
358 InstallerCallbacksTranslate::installProgressCallback,
359 new InstallerCallbacksTranslate::StatusCallbackStruct(
360 userdata, status_cb, progress_cb))));
362 UNHANDLED_EXCEPTION_HANDLER_END
365 EXPORT_API void wrt_install_plugin(
366 const char *pluginDir,
368 WrtPluginInstallerStatusCallback status_cb,
369 WrtProgressCallback progress_cb)
371 UNHANDLED_EXCEPTION_HANDLER_BEGIN
373 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
374 //Private data for status callback
375 //Resource is free in pluginInstallFinishedCallback
376 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
378 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
379 user_param, status_cb, progress_cb);
381 CONTROLLER_POST_EVENT(
382 Logic::InstallerController,
383 InstallerControllerEvents::InstallPluginEvent(
384 std::string(pluginDir),
385 PluginInstallerStruct(
386 InstallerCallbacksTranslate::
387 pluginInstallFinishedCallback,
388 InstallerCallbacksTranslate::
389 installProgressCallback, callbackStruct)));
391 UNHANDLED_EXCEPTION_HANDLER_END
394 EXPORT_API void wrt_install_all_plugins(
395 WrtAllPluginInstalledCallback installed_cb,
398 UNHANDLED_EXCEPTION_HANDLER_BEGIN
400 std::string installRequest =
401 std::string(GlobalConfig::GetPluginInstallInitializerName());
403 LogDebug("Install new plugins");
406 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
408 Catch(DPL::Semaphore::Exception::Base){
409 LogError("Failed to create installation lock");
415 if (-1 == stat(installRequest.c_str(), &tmp) ||
416 !S_ISREG(tmp.st_mode))
418 if (ENOENT == errno) {
419 LogDebug("Plugin installation not required");
421 LogDebug("Call SetAllinstallPluginCallback");
422 installed_cb(user_param);
424 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
427 LogWarning("Opening installation request file failed");
430 std::string PLUGIN_PATH =
431 std::string(GlobalConfig::GetDevicePluginPath());
434 dir = opendir(PLUGIN_PATH.c_str());
436 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
440 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
441 struct dirent* libdir;
445 std::list<std::string> pluginsPaths;
447 while ((libdir = readdir(dir)) != 0) {
448 if (strcmp(libdir->d_name, ".") == 0 ||
449 strcmp(libdir->d_name, "..") == 0)
454 std::string path = PLUGIN_PATH;
456 path += libdir->d_name;
460 if (stat(path.c_str(), &tmp) == -1) {
461 LogError("Failed to open file" << path);
465 if (!S_ISDIR(tmp.st_mode)) {
466 LogError("Not a directory" << path);
470 pluginsPaths.push_back(path);
473 wrt_count_plugin = pluginsPaths.size();
475 FOREACH(it, pluginsPaths) {
476 wrt_plugin_data *plugin_data = new wrt_plugin_data;
478 plugin_data->plugin_installed_cb = installed_cb;
479 plugin_data->plugin_path = const_cast<char*>(it->c_str());
480 plugin_data->user_data = user_param;
483 it->c_str(), static_cast<void*>(plugin_data),
484 plugin_install_status_cb,
485 plugin_install_progress_cb);
488 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
489 LogError("Failed to close dir: " << dir);
492 if (0 != unlink(installRequest.c_str())) {
493 LogError("Failed to remove file initializing plugin "
498 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
500 Catch(DPL::Semaphore::Exception::Base){
501 LogInfo("Failed to remove installation lock");
504 UNHANDLED_EXCEPTION_HANDLER_END
507 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
508 WrtInstallerInitCallback callback)
511 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
515 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
516 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
518 // Touch InstallerController Singleton
519 InstallerMainThreadSingleton::Instance().
520 TouchArchitectureOnlyInstaller();
525 callback(WRT_ERROR_NO_PATH, userdata);
530 CONTROLLER_POST_SYNC_EVENT(
531 Logic::InstallerController,
532 InstallerControllerEvents::
536 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
537 callback(WRT_SUCCESS, userdata);
540 catch (const DPL::Exception& ex)
542 LogError("Internal Error during Init:");
543 DPL::Exception::DisplayKnownException(ex);
545 callback(WRT_ERROR_INTERNAL, userdata);
554 EXPORT_API void wrt_installer_shutdown_for_tests()
558 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
560 // Installer termination
561 CONTROLLER_POST_SYNC_EVENT(
562 Logic::InstallerController,
563 InstallerControllerEvents::
566 // Global deinit check
567 LogInfo("Cleanup libxml2 global values.");
570 catch (const DPL::Exception& ex)
572 LogError("Internal Error during Shutdown:");
573 DPL::Exception::DisplayKnownException(ex);
577 EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname,
582 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : "
585 WidgetHandle handle = WidgetDAOReadOnly::getHandle(
586 DPL::FromASCIIString(pkgname));
587 *widget_handle = static_cast<int>(handle);
590 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
592 LogError("Error package name is not found");
593 return WRT_ERROR_PKGNAME_NOT_FOUND;
595 catch (const DPL::Exception& ex)
597 LogError("Internal Error during get widget id by package name");
598 DPL::Exception::DisplayKnownException(ex);
599 return WRT_ERROR_INTERNAL;
603 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid,
608 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : "
611 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
612 WidgetHandle handle = WidgetDAOReadOnly::getHandle(widget_guid);
613 *widget_handle = static_cast<int>(handle);
616 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
618 LogError("Error package name is not found");
619 return WRT_ERROR_PKGNAME_NOT_FOUND;
621 catch (const DPL::Exception& ex)
623 LogError("Internal Error during get widget id by package name");
624 DPL::Exception::DisplayKnownException(ex);
625 return WRT_ERROR_INTERNAL;