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;
69 WidgetUpdateMode::Type result = WidgetUpdateMode::Zero;
70 if (updateMode & WRT_WIM_NOT_INSTALLED) {
71 result = result | WidgetUpdateMode::NotInstalled;
74 if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) {
75 result = result | WidgetUpdateMode::IncomingVersionNotStd;
78 if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) {
79 result = result | WidgetUpdateMode::ExistingVersionNotStd;
82 if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) {
83 result = result | WidgetUpdateMode::BothVersionsNotStd;
86 if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) {
87 result = result | WidgetUpdateMode::ExistingVersionOlder;
90 if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) {
91 result = result | WidgetUpdateMode::ExistingVersionEqual;
94 if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) {
95 result = result | WidgetUpdateMode::ExistingVersionNewer;
101 const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
102 static int wrt_count_plugin;
104 static std::string cutOffFileName(const std::string& path)
106 size_t found = path.find_last_of("/");
107 if (found == std::string::npos) {
110 return path.substr(0, found);
114 static bool checkPath(const std::string& path)
117 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
120 LogError("Cannot access directory [ " << path << " ]");
124 static bool checkPaths()
127 if_ok &= (checkPath(cutOffFileName(
128 GlobalConfig::GetWrtDatabaseFilePath())));
131 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
132 "> does not exist.");
135 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
138 "Path <" << GlobalConfig::GetDevicePluginPath() <<
139 "> does not exist.");
142 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
145 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
146 "> does not exist.");
149 if_ok &= (checkPath(GlobalConfig::GetUserPreloadedWidgetPath()));
152 "Path <" << GlobalConfig::GetUserPreloadedWidgetPath() <<
153 "> does not exist.");
158 void plugin_install_status_cb(WrtErrStatus status,
163 wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
165 if (--wrt_count_plugin < 1) {
166 LogDebug("All plugins installation completed");
168 LogDebug("Call SetAllinstallpluginsCallback");
169 plugin_data->plugin_installed_cb(plugin_data->user_data);
172 if (status == WRT_SUCCESS) {
174 "plugin installation is successful: " <<
175 plugin_data->plugin_path);
179 LogError("Fail to install plugin : " << plugin_data->plugin_path);
182 case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
183 LogError("Failed : Plugin install path is wrong");
185 case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
186 LogError("Failed : Plugin Metafile Error");
188 case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
189 LogError("Failed : This Plugin is already installed");
191 case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
192 LogError("Failed : Library Error. Missing symbol or structures");
194 case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
195 LogError("Failed : Waiting for plugin dependencies");
197 case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
198 LogError("Failed : Lock Error");
200 case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
201 LogError("Failed : Unkown Error");
208 void plugin_install_progress_cb(float percent,
209 const char* description,
212 char *plugin_path = static_cast<char*>(userdata);
214 LogInfo("Install plugin : " << plugin_path <<
215 ", Progress : " << percent <<
216 ", Description : " << description);
219 EXPORT_API int wrt_installer_init(void *userdata,
220 WrtInstallerInitCallback callback)
223 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 // Initialize ValidationCore - this must be done before AttachDatabases
241 ValidationCore::VCoreInit(
242 std::string(GlobalConfig::GetFingerprintListFile()),
243 std::string(GlobalConfig::GetFingerprintListSchema()),
244 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
246 InstallerMainThreadSingleton::Instance().AttachDatabases();
248 //checking for correct DB version
249 // if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR))
251 // LogError("WRONG VERSION OF WRT DATABASE");
252 // Assert(false && "WRONG VERSION OF WRT DATABASE");
255 LogWarning("Database check not implemented!");
257 LogInfo("Prepare libxml2 to work in multithreaded program.");
260 // Initialize Language Subtag registry
261 LanguageSubtagRstTreeSingleton::Instance().Initialize();
264 CONTROLLER_POST_SYNC_EVENT(
265 Logic::InstallerController,
266 InstallerControllerEvents::
269 // Install deferred widget packages
270 CONTROLLER_POST_EVENT(
271 Logic::InstallerController,
272 InstallerControllerEvents::
273 InstallDeferredWidgetPackagesEvent());
276 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
277 callback(WRT_SUCCESS, userdata);
279 } catch (const DPL::Exception& ex) {
280 LogError("Internal Error during Init:");
281 DPL::Exception::DisplayKnownException(ex);
283 callback(WRT_ERROR_INTERNAL, userdata);
291 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.");
310 } catch (const DPL::Exception& ex) {
311 LogError("Internal Error during Shutdown:");
312 DPL::Exception::DisplayKnownException(ex);
316 EXPORT_API void wrt_install_widget(
319 WrtInstallerStatusCallback status_cb,
320 WrtProgressCallback progress_cb,
321 wrt_widget_update_mode_t update_mode,
324 std::shared_ptr<PackageManager::
325 IPkgmgrSignal> pkgmgrInterface
328 UNHANDLED_EXCEPTION_HANDLER_BEGIN
330 LogInfo("[WRT-API] INSTALL WIDGET: " << path);
331 // Post installation event
332 CONTROLLER_POST_EVENT(
333 Logic::InstallerController,
334 InstallerControllerEvents::InstallWidgetEvent(
335 path, WidgetInstallationStruct(
336 InstallerCallbacksTranslate::installFinishedCallback,
337 InstallerCallbacksTranslate::installProgressCallback,
338 new InstallerCallbacksTranslate::StatusCallbackStruct(
339 userdata, status_cb, progress_cb),
340 translateWidgetUpdateMode(update_mode),
345 UNHANDLED_EXCEPTION_HANDLER_END
348 EXPORT_API void wrt_uninstall_widget(
349 const char * const tzAppid,
351 WrtInstallerStatusCallback status_cb,
352 WrtProgressCallback progress_cb,
353 std::shared_ptr<PackageManager::
354 IPkgmgrSignal> pkgmgrSignalInterface)
356 UNHANDLED_EXCEPTION_HANDLER_BEGIN
358 std::string tizenAppid(tzAppid);
359 LogInfo("[WRT-API] UNINSTALL WIDGET: " << tizenAppid);
360 // Post uninstallation event
361 CONTROLLER_POST_EVENT(
362 Logic::InstallerController,
363 InstallerControllerEvents::UninstallWidgetEvent(
365 WidgetUninstallationStruct(
366 InstallerCallbacksTranslate::uninstallFinishedCallback,
367 InstallerCallbacksTranslate::installProgressCallback,
368 new InstallerCallbacksTranslate::StatusCallbackStruct(
369 userdata, status_cb, progress_cb),
370 pkgmgrSignalInterface
375 UNHANDLED_EXCEPTION_HANDLER_END
378 EXPORT_API void wrt_install_plugin(
379 const char *pluginDir,
381 WrtPluginInstallerStatusCallback status_cb,
382 WrtProgressCallback progress_cb)
384 UNHANDLED_EXCEPTION_HANDLER_BEGIN
386 LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
387 //Private data for status callback
388 //Resource is free in pluginInstallFinishedCallback
389 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
391 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
392 user_param, status_cb, progress_cb);
394 CONTROLLER_POST_EVENT(
395 Logic::InstallerController,
396 InstallerControllerEvents::InstallPluginEvent(
397 std::string(pluginDir),
398 PluginInstallerStruct(
399 InstallerCallbacksTranslate::
400 pluginInstallFinishedCallback,
401 InstallerCallbacksTranslate::
402 installProgressCallback, callbackStruct)));
404 UNHANDLED_EXCEPTION_HANDLER_END
407 EXPORT_API void wrt_install_all_plugins(
408 WrtAllPluginInstalledCallback installed_cb,
411 UNHANDLED_EXCEPTION_HANDLER_BEGIN
413 std::string installRequest =
414 std::string(GlobalConfig::GetPluginInstallInitializerName());
416 LogDebug("Install new plugins");
419 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
421 Catch(DPL::Semaphore::Exception::Base){
422 LogError("Failed to create installation lock");
428 if (-1 == stat(installRequest.c_str(), &tmp) ||
429 !S_ISREG(tmp.st_mode))
431 if (ENOENT == errno) {
432 LogDebug("Plugin installation not required");
434 LogDebug("Call SetAllinstallPluginCallback");
435 installed_cb(user_param);
437 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
440 LogWarning("Opening installation request file failed");
443 std::string PLUGIN_PATH =
444 std::string(GlobalConfig::GetDevicePluginPath());
447 dir = opendir(PLUGIN_PATH.c_str());
449 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
453 LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
454 struct dirent libdir;
455 struct dirent *result;
460 std::list<std::string> pluginsPaths;
462 for (return_code = readdir_r(dir, &libdir, &result);
463 result != NULL && return_code == 0;
464 return_code = readdir_r(dir, &libdir, &result))
466 if (strcmp(libdir.d_name, ".") == 0 ||
467 strcmp(libdir.d_name, "..") == 0)
472 std::string path = PLUGIN_PATH;
474 path += libdir.d_name;
478 if (stat(path.c_str(), &tmp) == -1) {
479 LogError("Failed to open file" << path);
483 if (!S_ISDIR(tmp.st_mode)) {
484 LogError("Not a directory" << path);
488 pluginsPaths.push_back(path);
491 wrt_count_plugin = pluginsPaths.size();
493 FOREACH(it, pluginsPaths) {
494 wrt_plugin_data *plugin_data = new wrt_plugin_data;
496 plugin_data->plugin_installed_cb = installed_cb;
497 plugin_data->plugin_path = const_cast<char*>(it->c_str());
498 plugin_data->user_data = user_param;
501 it->c_str(), static_cast<void*>(plugin_data),
502 plugin_install_status_cb,
503 plugin_install_progress_cb);
506 if (return_code != 0 || errno != 0) {
507 LogError("readdir_r() failed with " << DPL::GetErrnoString());
511 if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
512 LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
513 << DPL::GetErrnoString());
516 if (0 != unlink(installRequest.c_str())) {
517 LogError("Failed to remove file initializing plugin "
522 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
524 Catch(DPL::Semaphore::Exception::Base){
525 LogInfo("Failed to remove installation lock");
528 UNHANDLED_EXCEPTION_HANDLER_END
531 EXPORT_API int wrt_installer_init_for_tests(void *userdata,
532 WrtInstallerInitCallback callback)
535 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
538 LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
539 LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
541 // Touch InstallerController Singleton
542 InstallerMainThreadSingleton::Instance().
543 TouchArchitectureOnlyInstaller();
548 callback(WRT_ERROR_NO_PATH, userdata);
553 CONTROLLER_POST_SYNC_EVENT(
554 Logic::InstallerController,
555 InstallerControllerEvents::
559 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
560 callback(WRT_SUCCESS, userdata);
562 } catch (const DPL::Exception& ex) {
563 LogError("Internal Error during Init:");
564 DPL::Exception::DisplayKnownException(ex);
566 callback(WRT_ERROR_INTERNAL, userdata);
575 EXPORT_API void wrt_installer_shutdown_for_tests()
578 LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
580 // Installer termination
581 CONTROLLER_POST_SYNC_EVENT(
582 Logic::InstallerController,
583 InstallerControllerEvents::
586 // Global deinit check
587 LogInfo("Cleanup libxml2 global values.");
589 } catch (const DPL::Exception& ex) {
590 LogError("Internal Error during Shutdown:");
591 DPL::Exception::DisplayKnownException(ex);
595 EXPORT_API WrtErrStatus wrt_get_widget_by_guid(std::string & tzAppid,
596 const std::string & guid)
599 LogInfo("[WRT-API] GETTING WIDGET PACKAGE NAME BY WidgetID : "
602 WidgetGUID widget_guid = DPL::FromUTF8String(guid);
603 WrtDB::WidgetDAOReadOnly dao(widget_guid);
604 tzAppid = DPL::ToUTF8String(dao.getTzAppId());
606 } catch (WidgetDAOReadOnly::Exception::WidgetNotExist&) {
607 LogError("Error package name is not found");
608 return WRT_ERROR_PKGNAME_NOT_FOUND;
609 } catch (const DPL::Exception& ex) {
610 LogError("Internal Error during get widget id by package name");
611 DPL::Exception::DisplayKnownException(ex);
612 return WRT_ERROR_INTERNAL;