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/sstream.h>
32 #include <libxml/parser.h>
34 #include <wrt_installer_api.h>
35 #include <installer_callbacks_translate.h>
36 #include <installer_controller.h>
37 #include <security_controller.h>
38 #include <language_subtag_rst_tree.h>
39 #include <dpl/localization/localization_utils.h>
40 #include <dpl/wrt-dao-ro/global_config.h>
41 #include <dpl/utils/widget_version.h>
42 #include <dpl/popup/popup_manager.h>
43 #include <dpl/popup/popup_controller.h>
44 #include <attribute_facade.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 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::GetFactoryInstalledWidgetPath()));
144 "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() <<
145 "> does not exist.");
148 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
151 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
152 "> does not exist.");
157 void plugin_install_status_cb(WrtErrStatus status,
162 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
164 if (--wrt_count_plugin < 1) {
165 LogDebug("All plugins installation completed");
167 LogDebug("Call SetAllinstallpluginsCallback");
168 plugin_data->plugin_installed_cb(plugin_data->user_data);
171 if (status == WRT_SUCCESS) {
173 "plugin installation is successful: " <<
174 plugin_data->plugin_path);
178 LogError("Fail to install plugin : " << plugin_data->plugin_path);
181 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
182 LogError("Failed : Plugin install path is wrong");
184 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
185 LogError("Failed : Plugin Metafile Error");
187 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
188 LogError("Failed : This Plugin is already installed");
190 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
191 LogError("Failed : Library Error. Missing symbol or structures");
193 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
194 LogError("Failed : Waiting for plugin dependencies");
196 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
197 LogError("Failed : Lock Error");
199 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
200 LogError("Failed : Unkown Error");
207 void plugin_install_progress_cb(float percent,
208 const char* description,
211 char *plugin_path = static_cast<char*>(userdata);
213 LogInfo("Install plugin : " << plugin_path <<
214 ", Progress : " << percent <<
215 ", Description : " << description);
218 EXPORT_API int wrt_installer_init(void *userdata,
219 WrtInstallerInitCallback callback)
222 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
226 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
227 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
229 // Touch InstallerController Singleton
230 InstallerMainThreadSingleton::Instance().TouchArchitecture();
235 callback(WRT_ERROR_NO_PATH, userdata);
240 InstallerMainThreadSingleton::Instance().AttachDatabases();
242 //checking for correct DB version
243 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
244 // LogError("WRONG VERSION OF WRT DATABASE");
245 // Assert(false && "WRONG VERSION OF WRT DATABASE");
248 LogWarning("Database check not implemented!");
250 LogInfo("Prepare libxml2 to work in multithreaded program.");
253 using namespace DPL::Popup;
254 // Initialize popup manager
255 PopupManagerSingleton::Instance().Initialize(
256 PopupRendererPtr(new PopupRenderer));
258 // Initialize Language Subtag registry
259 LanguageSubtagRstTreeSingleton::Instance().Initialize();
260 LocalizationUtils::Initialize();
262 // Initialize ValidationCore
263 ValidationCore::VCoreInit(
264 std::string(GlobalConfig::GetFingerprintListFile()),
265 std::string(GlobalConfig::GetFingerprintListSchema()),
266 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
268 // Security Logic initialization
269 CONTROLLER_POST_SYNC_EVENT(
271 SecurityControllerEvents::InitializeSyncEvent());
274 CONTROLLER_POST_SYNC_EVENT(
276 InstallerControllerEvents::
279 // Install deferred widget packages
280 CONTROLLER_POST_EVENT(
282 InstallerControllerEvents::
283 InstallDeferredWidgetPackagesEvent());
286 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
287 callback(WRT_SUCCESS, userdata);
290 catch (const DPL::Exception& ex)
292 LogError("Internal Error during Init:");
293 DPL::Exception::DisplayKnownException(ex);
295 callback(WRT_ERROR_INTERNAL, userdata);
303 EXPORT_API void wrt_installer_shutdown()
307 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
309 // Deinitialize Security Logic
310 CONTROLLER_POST_SYNC_EVENT(
312 SecurityControllerEvents::
313 TerminateSyncEvent());
315 // Installer termination
316 CONTROLLER_POST_SYNC_EVENT(
318 InstallerControllerEvents::
321 InstallerMainThreadSingleton::Instance().DetachDatabases();
323 // Global deinit check
324 LogInfo("Cleanup libxml2 global values.");
327 // Deinitialize popup manager
328 DPL::Popup::PopupManagerSingleton::Instance().Deinitialize();
330 catch (const DPL::Exception& ex)
332 LogError("Internal Error during Shutdown:");
333 DPL::Exception::DisplayKnownException(ex);
337 EXPORT_API void wrt_install_widget(const char *path,
339 WrtInstallerStatusCallback status_cb,
340 WrtProgressCallback progress_cb,
341 wrt_widget_update_mode_t update_mode)
343 UNHANDLED_EXCEPTION_HANDLER_BEGIN
345 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
346 // Post installation event
347 CONTROLLER_POST_EVENT(
349 InstallerControllerEvents::InstallWidgetEvent(
350 path, WidgetInstallationStruct(
351 InstallerCallbacksTranslate::installFinishedCallback,
352 InstallerCallbacksTranslate::installProgressCallback,
353 new InstallerCallbacksTranslate::StatusCallbackStruct(
354 userdata, status_cb, progress_cb),
355 translateWidgetUpdateMode(update_mode))));
357 UNHANDLED_EXCEPTION_HANDLER_END
360 EXPORT_API void wrt_uninstall_widget(int widget_handle,
362 WrtInstallerStatusCallback status_cb,
363 WrtProgressCallback progress_cb)
365 UNHANDLED_EXCEPTION_HANDLER_BEGIN
367 LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle);
368 // Post uninstallation event
369 CONTROLLER_POST_EVENT(
371 InstallerControllerEvents::UninstallWidgetEvent(
373 WidgetUninstallationStruct(
374 InstallerCallbacksTranslate::uninstallFinishedCallback,
375 InstallerCallbacksTranslate::installProgressCallback,
376 new InstallerCallbacksTranslate::StatusCallbackStruct(
377 userdata, status_cb, progress_cb))));
379 UNHANDLED_EXCEPTION_HANDLER_END
382 EXPORT_API void wrt_install_plugin(
383 const char *pluginDir,
385 WrtPluginInstallerStatusCallback status_cb,
386 WrtProgressCallback progress_cb)
388 UNHANDLED_EXCEPTION_HANDLER_BEGIN
390 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
391 //Private data for status callback
392 //Resource is free in pluginInstallFinishedCallback
393 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
395 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
396 user_param, status_cb, progress_cb);
397 // Added geolocation feature in FeaturesList DB for installing
398 // widget using gelocation feature.
399 // If other strange features are added, it will be changed
400 // for using all of strange features.
401 if (strcmp(pluginDir,
402 GlobalConfig::GetW3CGeolocationFeatureName()) == 0)
404 CONTROLLER_POST_EVENT(
406 InstallerControllerEvents::InstallPluginGeolocationEvent(
407 PluginInstallerStruct(
408 InstallerCallbacksTranslate::
409 pluginInstallFinishedCallback,
410 InstallerCallbacksTranslate::
411 installProgressCallback, callbackStruct)));
413 CONTROLLER_POST_EVENT(
415 InstallerControllerEvents::InstallPluginEvent(
416 std::string(pluginDir),
417 PluginInstallerStruct(
418 InstallerCallbacksTranslate::
419 pluginInstallFinishedCallback,
420 InstallerCallbacksTranslate::
421 installProgressCallback, callbackStruct)));
424 UNHANDLED_EXCEPTION_HANDLER_END
427 EXPORT_API void wrt_install_all_plugins(
428 WrtAllPluginInstalledCallback installed_cb,
431 UNHANDLED_EXCEPTION_HANDLER_BEGIN
433 std::string installRequest =
434 std::string(GlobalConfig::GetPluginInstallInitializerName());
436 LogDebug("Install new plugins");
439 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
441 Catch(DPL::Semaphore::Exception::Base){
442 LogError("Failed to create installation lock");
448 if (-1 == stat(installRequest.c_str(), &tmp) ||
449 !S_ISREG(tmp.st_mode))
451 if (ENOENT == errno) {
452 LogDebug("Plugin installation not required");
454 LogDebug("Call SetAllinstallPluginCallback");
455 installed_cb(user_param);
457 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
460 LogWarning("Opening installation request file failed");
463 std::string PLUGIN_PATH =
464 std::string(GlobalConfig::GetDevicePluginPath());
467 dir = opendir(PLUGIN_PATH.c_str());
469 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
473 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
474 struct dirent* libdir;
478 std::list<std::string> pluginsPaths;
480 while ((libdir = readdir(dir)) != 0) {
481 if (strcmp(libdir->d_name, ".") == 0 ||
482 strcmp(libdir->d_name, "..") == 0)
487 std::string path = PLUGIN_PATH;
489 path += libdir->d_name;
493 if (stat(path.c_str(), &tmp) == -1) {
494 LogError("Failed to open file" << path);
498 if (!S_ISDIR(tmp.st_mode)) {
499 LogError("Not a directory" << path);
503 pluginsPaths.push_back(path);
506 wrt_count_plugin = pluginsPaths.size();
508 FOREACH(it, pluginsPaths) {
509 wrt_plugin_data *plugin_data = new wrt_plugin_data;
511 plugin_data->plugin_installed_cb = installed_cb;
512 plugin_data->plugin_path = const_cast<char*>(it->c_str());
513 plugin_data->user_data = user_param;
516 it->c_str(), static_cast<void*>(plugin_data),
517 plugin_install_status_cb,
518 plugin_install_progress_cb);
522 GlobalConfig::GetW3CGeolocationFeatureName(), NULL, NULL, NULL);
524 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
525 LogError("Failed to close dir: " << dir);
528 if (0 != unlink(installRequest.c_str())) {
529 LogError("Failed to remove file initializing plugin "
534 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
536 Catch(DPL::Semaphore::Exception::Base){
537 LogInfo("Failed to remove installation lock");
540 UNHANDLED_EXCEPTION_HANDLER_END
543 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
544 WrtInstallerInitCallback callback)
547 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
551 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
552 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
554 // Touch InstallerController Singleton
555 InstallerMainThreadSingleton::Instance().
556 TouchArchitectureOnlyInstaller();
561 callback(WRT_ERROR_NO_PATH, userdata);
566 CONTROLLER_POST_SYNC_EVENT(
568 InstallerControllerEvents::
572 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
573 callback(WRT_SUCCESS, userdata);
576 catch (const DPL::Exception& ex)
578 LogError("Internal Error during Init:");
579 DPL::Exception::DisplayKnownException(ex);
581 callback(WRT_ERROR_INTERNAL, userdata);
590 EXPORT_API void wrt_installer_shutdown_for_tests()
594 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
596 // Installer termination
597 CONTROLLER_POST_SYNC_EVENT(
599 InstallerControllerEvents::
602 // Global deinit check
603 LogInfo("Cleanup libxml2 global values.");
606 catch (const DPL::Exception& ex)
608 LogError("Internal Error during Shutdown:");
609 DPL::Exception::DisplayKnownException(ex);
613 EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname,
618 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : "
621 WidgetHandle handle = WidgetDAO::getHandle(
622 DPL::FromASCIIString(pkgname));
623 *widget_handle = static_cast<int>(handle);
626 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
628 LogError("Error package name is not found");
629 return WRT_ERROR_PKGNAME_NOT_FOUND;
631 catch (const DPL::Exception& ex)
633 LogError("Internal Error during get widget id by package name");
634 DPL::Exception::DisplayKnownException(ex);
635 return WRT_ERROR_INTERNAL;
639 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid,
644 LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : "
647 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
648 WidgetHandle handle = WidgetDAO::getHandle(widget_guid);
649 *widget_handle = static_cast<int>(handle);
652 catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
654 LogError("Error package name is not found");
655 return WRT_ERROR_PKGNAME_NOT_FOUND;
657 catch (const DPL::Exception& ex)
659 LogError("Internal Error during get widget id by package name");
660 DPL::Exception::DisplayKnownException(ex);
661 return WRT_ERROR_INTERNAL;