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 WidgetUpdateMode::Type result = WidgetUpdateMode::Zero;
67 if (updateMode & WRT_WIM_NOT_INSTALLED) {
68 result = result | WidgetUpdateMode::NotInstalled;
71 if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) {
72 result = result | WidgetUpdateMode::IncomingVersionNotStd;
75 if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) {
76 result = result | WidgetUpdateMode::ExistingVersionNotStd;
79 if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) {
80 result = result | WidgetUpdateMode::BothVersionsNotStd;
83 if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) {
84 result = result | WidgetUpdateMode::ExistingVersionOlder;
87 if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) {
88 result = result | WidgetUpdateMode::ExistingVersionEqual;
91 if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) {
92 result = result | WidgetUpdateMode::ExistingVersionNewer;
98 const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
99 static int wrt_count_plugin;
101 static std::string cutOffFileName(const std::string& path)
103 size_t found = path.find_last_of("/");
104 if (found == std::string::npos) {
107 return path.substr(0, found);
111 static bool checkPath(const std::string& path)
114 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
117 LogError("Cannot access directory [ " << path << " ]");
121 static bool checkPaths()
124 if_ok &= (checkPath(cutOffFileName(
125 GlobalConfig::GetWrtDatabaseFilePath())));
128 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
129 "> does not exist.");
132 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
135 "Path <" << GlobalConfig::GetDevicePluginPath() <<
136 "> does not exist.");
139 if_ok &= (checkPath(GlobalConfig::GetFactoryInstalledWidgetPath()));
142 "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() <<
143 "> does not exist.");
146 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
149 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
150 "> does not exist.");
155 void plugin_install_status_cb(WrtErrStatus status,
160 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
162 if (--wrt_count_plugin < 1) {
163 LogDebug("All plugins installation completed");
165 LogDebug("Call SetAllinstallpluginsCallback");
166 plugin_data->plugin_installed_cb(plugin_data->user_data);
169 if (status == WRT_SUCCESS) {
171 "plugin installation is successful: " <<
172 plugin_data->plugin_path);
176 LogError("Fail to install plugin : " << plugin_data->plugin_path);
179 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
180 LogError("Failed : Plugin install path is wrong");
182 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
183 LogError("Failed : Plugin Metafile Error");
185 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
186 LogError("Failed : This Plugin is already installed");
188 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
189 LogError("Failed : Library Error. Missing symbol or structures");
191 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
192 LogError("Failed : Waiting for plugin dependencies");
194 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
195 LogError("Failed : Lock Error");
197 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
198 LogError("Failed : Unkown Error");
205 void plugin_install_progress_cb(float percent,
206 const char* description,
209 char *plugin_path = static_cast<char*>(userdata);
211 LogInfo("Install plugin : " << plugin_path <<
212 ", Progress : " << percent <<
213 ", Description : " << description);
216 EXPORT_API int wrt_installer_init(void *userdata,
217 WrtInstallerInitCallback callback)
220 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
224 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
225 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
227 // Touch InstallerController Singleton
228 InstallerMainThreadSingleton::Instance().TouchArchitecture();
233 callback(WRT_ERROR_NO_PATH, userdata);
238 // Initialize ValidationCore - this must be done before AttachDatabases
239 ValidationCore::VCoreInit(
240 std::string(GlobalConfig::GetFingerprintListFile()),
241 std::string(GlobalConfig::GetFingerprintListSchema()),
242 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
244 InstallerMainThreadSingleton::Instance().AttachDatabases();
246 //checking for correct DB version
247 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
248 // LogError("WRONG VERSION OF WRT DATABASE");
249 // Assert(false && "WRONG VERSION OF WRT DATABASE");
252 LogWarning("Database check not implemented!");
254 LogInfo("Prepare libxml2 to work in multithreaded program.");
257 // Initialize Language Subtag registry
258 LanguageSubtagRstTreeSingleton::Instance().Initialize();
261 CONTROLLER_POST_SYNC_EVENT(
262 Logic::InstallerController,
263 InstallerControllerEvents::
266 // Install deferred widget packages
267 CONTROLLER_POST_EVENT(
268 Logic::InstallerController,
269 InstallerControllerEvents::
270 InstallDeferredWidgetPackagesEvent());
273 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
274 callback(WRT_SUCCESS, userdata);
277 catch (const DPL::Exception& ex)
279 LogError("Internal Error during Init:");
280 DPL::Exception::DisplayKnownException(ex);
282 callback(WRT_ERROR_INTERNAL, userdata);
290 EXPORT_API void wrt_installer_shutdown()
294 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
296 // Installer termination
297 CONTROLLER_POST_SYNC_EVENT(
298 Logic::InstallerController,
299 InstallerControllerEvents::
302 InstallerMainThreadSingleton::Instance().DetachDatabases();
304 // This must be done after DetachDatabase
305 ValidationCore::VCoreDeinit();
307 // Global deinit check
308 LogInfo("Cleanup libxml2 global values.");
312 catch (const DPL::Exception& ex)
314 LogError("Internal Error during Shutdown:");
315 DPL::Exception::DisplayKnownException(ex);
319 EXPORT_API void wrt_install_widget(const char *path,
321 WrtInstallerStatusCallback status_cb,
322 WrtProgressCallback progress_cb,
323 wrt_widget_update_mode_t update_mode,
326 UNHANDLED_EXCEPTION_HANDLER_BEGIN
328 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
329 // Post installation event
330 CONTROLLER_POST_EVENT(
331 Logic::InstallerController,
332 InstallerControllerEvents::InstallWidgetEvent(
333 path, WidgetInstallationStruct(
334 InstallerCallbacksTranslate::installFinishedCallback,
335 InstallerCallbacksTranslate::installProgressCallback,
336 new InstallerCallbacksTranslate::StatusCallbackStruct(
337 userdata, status_cb, progress_cb),
338 translateWidgetUpdateMode(update_mode),
341 UNHANDLED_EXCEPTION_HANDLER_END
344 EXPORT_API void wrt_uninstall_widget(int widget_handle,
346 WrtInstallerStatusCallback status_cb,
347 WrtProgressCallback progress_cb)
349 UNHANDLED_EXCEPTION_HANDLER_BEGIN
351 LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle);
352 // Post uninstallation event
353 CONTROLLER_POST_EVENT(
354 Logic::InstallerController,
355 InstallerControllerEvents::UninstallWidgetEvent(
357 WidgetUninstallationStruct(
358 InstallerCallbacksTranslate::uninstallFinishedCallback,
359 InstallerCallbacksTranslate::installProgressCallback,
360 new InstallerCallbacksTranslate::StatusCallbackStruct(
361 userdata, status_cb, progress_cb))));
363 UNHANDLED_EXCEPTION_HANDLER_END
366 EXPORT_API void wrt_install_plugin(
367 const char *pluginDir,
369 WrtPluginInstallerStatusCallback status_cb,
370 WrtProgressCallback progress_cb)
372 UNHANDLED_EXCEPTION_HANDLER_BEGIN
374 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
375 //Private data for status callback
376 //Resource is free in pluginInstallFinishedCallback
377 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
379 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
380 user_param, status_cb, progress_cb);
382 CONTROLLER_POST_EVENT(
383 Logic::InstallerController,
384 InstallerControllerEvents::InstallPluginEvent(
385 std::string(pluginDir),
386 PluginInstallerStruct(
387 InstallerCallbacksTranslate::
388 pluginInstallFinishedCallback,
389 InstallerCallbacksTranslate::
390 installProgressCallback, callbackStruct)));
392 UNHANDLED_EXCEPTION_HANDLER_END
395 EXPORT_API void wrt_install_all_plugins(
396 WrtAllPluginInstalledCallback installed_cb,
399 UNHANDLED_EXCEPTION_HANDLER_BEGIN
401 std::string installRequest =
402 std::string(GlobalConfig::GetPluginInstallInitializerName());
404 LogDebug("Install new plugins");
407 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
409 Catch(DPL::Semaphore::Exception::Base){
410 LogError("Failed to create installation lock");
416 if (-1 == stat(installRequest.c_str(), &tmp) ||
417 !S_ISREG(tmp.st_mode))
419 if (ENOENT == errno) {
420 LogDebug("Plugin installation not required");
422 LogDebug("Call SetAllinstallPluginCallback");
423 installed_cb(user_param);
425 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
428 LogWarning("Opening installation request file failed");
431 std::string PLUGIN_PATH =
432 std::string(GlobalConfig::GetDevicePluginPath());
435 dir = opendir(PLUGIN_PATH.c_str());
437 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
441 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
442 struct dirent* libdir;
446 std::list<std::string> pluginsPaths;
448 while ((libdir = readdir(dir)) != 0) {
449 if (strcmp(libdir->d_name, ".") == 0 ||
450 strcmp(libdir->d_name, "..") == 0)
455 std::string path = PLUGIN_PATH;
457 path += libdir->d_name;
461 if (stat(path.c_str(), &tmp) == -1) {
462 LogError("Failed to open file" << path);
466 if (!S_ISDIR(tmp.st_mode)) {
467 LogError("Not a directory" << path);
471 pluginsPaths.push_back(path);
474 wrt_count_plugin = pluginsPaths.size();
476 FOREACH(it, pluginsPaths) {
477 wrt_plugin_data *plugin_data = new wrt_plugin_data;
479 plugin_data->plugin_installed_cb = installed_cb;
480 plugin_data->plugin_path = const_cast<char*>(it->c_str());
481 plugin_data->user_data = user_param;
484 it->c_str(), static_cast<void*>(plugin_data),
485 plugin_install_status_cb,
486 plugin_install_progress_cb);
489 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
490 LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
491 << DPL::GetErrnoString());
494 if (0 != unlink(installRequest.c_str())) {
495 LogError("Failed to remove file initializing plugin "
500 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
502 Catch(DPL::Semaphore::Exception::Base){
503 LogInfo("Failed to remove installation lock");
506 UNHANDLED_EXCEPTION_HANDLER_END
509 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
510 WrtInstallerInitCallback callback)
513 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
517 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
518 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
520 // Touch InstallerController Singleton
521 InstallerMainThreadSingleton::Instance().
522 TouchArchitectureOnlyInstaller();
527 callback(WRT_ERROR_NO_PATH, userdata);
532 CONTROLLER_POST_SYNC_EVENT(
533 Logic::InstallerController,
534 InstallerControllerEvents::
538 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
539 callback(WRT_SUCCESS, userdata);
542 catch (const DPL::Exception& ex)
544 LogError("Internal Error during Init:");
545 DPL::Exception::DisplayKnownException(ex);
547 callback(WRT_ERROR_INTERNAL, userdata);
556 EXPORT_API void wrt_installer_shutdown_for_tests()
560 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
562 // Installer termination
563 CONTROLLER_POST_SYNC_EVENT(
564 Logic::InstallerController,
565 InstallerControllerEvents::
568 // Global deinit check
569 LogInfo("Cleanup libxml2 global values.");
572 catch (const DPL::Exception& ex)
574 LogError("Internal Error during Shutdown:");
575 DPL::Exception::DisplayKnownException(ex);
579 EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname,
584 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : "
587 WidgetHandle handle = WidgetDAOReadOnly::getHandle(
588 DPL::FromASCIIString(pkgname));
589 *widget_handle = static_cast<int>(handle);
592 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
594 LogError("Error package name is not found");
595 return WRT_ERROR_PKGNAME_NOT_FOUND;
597 catch (const DPL::Exception& ex)
599 LogError("Internal Error during get widget id by package name");
600 DPL::Exception::DisplayKnownException(ex);
601 return WRT_ERROR_INTERNAL;
605 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid,
610 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : "
613 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
614 WidgetHandle handle = WidgetDAOReadOnly::getHandle(widget_guid);
615 *widget_handle = static_cast<int>(handle);
618 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
620 LogError("Error package name is not found");
621 return WRT_ERROR_PKGNAME_NOT_FOUND;
623 catch (const DPL::Exception& ex)
625 LogError("Internal Error during get widget id by package name");
626 DPL::Exception::DisplayKnownException(ex);
627 return WRT_ERROR_INTERNAL;