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.
16 /* @file wrt-installer.cpp
18 * @brief Implementation file for installer
21 #include "wrt-installer.h"
22 #include "plugin_utils.h"
30 #include <sys/resource.h>
32 #include <libxml/parser.h>
33 #include <dpl/log/log.h>
34 #include <dpl/optional_typedefs.h>
35 #include <dpl/wrt-dao-ro/global_config.h>
36 #include <dpl/wrt-dao-ro/config_parser_data.h>
37 #include <dpl/abstract_waitable_input_adapter.h>
38 #include <dpl/abstract_waitable_output_adapter.h>
39 #include <dpl/binary_queue.h>
41 #include <dpl/errno_string.h>
42 #include <dpl/localization/w3c_file_localization.h>
43 #include <dpl/optional_typedefs.h>
44 #include <dpl/utils/widget_version.h>
45 #include <dpl/utils/wrt_global_settings.h>
46 #include <dpl/utils/wrt_utility.h>
47 #include <dpl/wrt-dao-ro/config_parser_data.h>
48 #include <dpl/wrt-dao-ro/global_config.h>
49 #include <dpl/wrt-dao-ro/WrtDatabase.h>
50 #include <dpl/zip_input.h>
52 #include <wrt-commons/i18n-dao-ro/i18n_database.h>
54 #include <vcore/VCore.h>
56 #include <Elementary.h>
58 #include <installer_callbacks_translate.h>
59 #include <installer_controller.h>
60 #include <installer_log.h>
61 #include <installer_main_thread.h>
62 #include <language_subtag_rst_tree.h>
63 #include <parser_runner.h>
64 #include <pkg-manager/pkgmgr_signal_dummy.h>
65 #include <pkgmgr-info.h>
66 #include <root_parser.h>
67 #include <widget_parser.h>
68 #include <wrt_install_mode.h>
69 #include <command_parser.h>
71 using namespace WrtDB;
73 namespace { // anonymous
74 const char * const PKGMGR_INSTALL_MSG = "Install widget";
75 const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
77 const char * const CONFIG_XML = "config.xml";
78 const char * const HYBRID_CONFIG_XML = "res/wgt/config.xml";
80 const unsigned int NOFILE_CNT_FOR_INSTALLER = 9999;
84 void operator()(void* x)
90 struct PluginInstallerData
93 std::string pluginPath;
96 std::string cutOffFileName(const std::string& path)
98 size_t found = path.find_last_of("/");
99 if (found == std::string::npos) {
102 return path.substr(0, found);
106 bool checkPath(const std::string& path)
109 if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
112 _E("Cannot access directory [ %s ]", path.c_str());
120 if_ok &= (checkPath(cutOffFileName(GlobalConfig::GetWrtDatabaseFilePath())));
121 if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
122 if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
123 if_ok &= (checkPath(GlobalConfig::GetUserPreloadedWidgetPath()));
128 } // namespace anonymous
130 WrtInstaller::WrtInstaller(int argc, char **argv) :
131 Application(argc, argv, "backend", false),
132 DPL::TaskDecl<WrtInstaller>(this),
134 m_initialized(false),
135 m_numPluginsToInstall(0),
139 m_startupPluginInstallation(false)
145 WrtInstaller::~WrtInstaller()
150 int WrtInstaller::getReturnStatus() const
152 return m_returnStatus;
155 void WrtInstaller::OnStop()
157 _D("Stopping Dummy Client");
160 void WrtInstaller::OnCreate()
162 _D("Creating DummyClient");
165 power_lock_state(POWER_STATE_SCREEN_OFF, 60*1000);
169 AddStep(&WrtInstaller::initStep);
171 std::string arg = m_argv[0];
173 using namespace PackageManager;
175 auto pkgmgrSignal = std::shared_ptr<PackageManager::PkgmgrSignal>(new PackageManager::PkgmgrSignal());
177 pkgmgrSignalInterface =
178 std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
179 std::shared_ptr<PackageManager::PkgmgrSignalDummy>(
180 new PackageManager::PkgmgrSignalDummy()));
183 return showHelpAndQuit();
188 if (arg.find("wrt-installer") != std::string::npos) {
190 return showHelpAndQuit();
194 if (arg == "-h" || arg == "--help") {
196 return showHelpAndQuit();
200 return showHelpAndQuit();
201 } else if (arg == "-p" || arg == "--install-plugins") {
203 return showHelpAndQuit();
206 if (!m_startupPluginInstallation) {
207 AddStep(&WrtInstaller::installPluginsStep);
209 _D("Plugin installation alredy started");
211 } else if (arg == "-i" || arg == "--install") {
213 return showHelpAndQuit();
217 if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
218 _D("Installing package directly from directory");
219 m_installMode.extension = InstallMode::ExtensionType::DIR;
221 _D("Installing from regular location");
222 m_installMode.extension = InstallMode::ExtensionType::WGT;
224 m_packagePath = m_argv[2];
226 pkgmgrSignal->initialize(m_argc, m_argv);
227 pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
228 AddStep(&WrtInstaller::installStep);
229 } else if (arg == "-ip" || arg == "--install-preload") {
230 _D("Install preload web app");
232 return showHelpAndQuit();
234 m_packagePath = m_argv[2];
235 m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
236 m_installMode.rootPath = InstallMode::RootPath::RO;
237 m_installMode.removable = false;
238 AddStep(&WrtInstaller::installStep);
239 } else if (arg == "-ipw" || arg == "--install-preload-writable") {
240 _D("Install preload web application to writable storage");
242 return showHelpAndQuit();
244 m_packagePath = m_argv[2];
245 m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
246 m_installMode.rootPath = InstallMode::RootPath::RW;
247 m_installMode.removable = true;
248 AddStep(&WrtInstaller::installStep);
249 } else if (arg == "-c" || arg == "--csc-update") {
250 // "path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true"
251 _D("Install & uninstall by csc configuration");
253 return showHelpAndQuit();
255 m_installMode.installTime = InstallMode::InstallTime::CSC;
256 std::string configuration = m_argv[2];
258 CommandParser::CscOption option;
259 if (!CommandParser::CscCommandParser(configuration, option)) {
260 return showHelpAndQuit();
263 if (0 == option.operation.compare(Command::VALUE_INSTALL)) {
264 m_installMode.extension = InstallMode::ExtensionType::WGT;
265 m_packagePath = option.path;
266 m_installMode.removable = option.removable;
267 m_installMode.cscPath = m_argv[2];
268 _D("operation = %s", option.operation.c_str());
269 _D("path = %s", m_packagePath.c_str());
270 _D("removable = %d", m_installMode.removable);
271 _D("csc Path = %s", m_installMode.cscPath.c_str());
272 AddStep(&WrtInstaller::installStep);
273 } else if (0 == option.operation.compare(Command::VALUE_UNINSTALL)){
274 m_packagePath = option.path;
275 _D("operation = %s", option.operation.c_str());
276 _D("path = %s", m_packagePath.c_str());
277 AddStep(&WrtInstaller::unistallWgtFileStep);
279 _E("Unknown operation : %s", option.operation.c_str());
280 return showHelpAndQuit();
282 } else if (arg == "-un" || arg == "--uninstall-name") {
284 return showHelpAndQuit();
288 m_argv[1] = (char*)"-d";
289 pkgmgrSignal->initialize(m_argc, m_argv);
290 pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
291 AddStep(&WrtInstaller::uninstallPkgNameStep);
292 } else if (arg == "-up" || arg == "--uninstall-packagepath") {
294 return showHelpAndQuit();
296 m_packagePath = m_argv[2];
297 AddStep(&WrtInstaller::unistallWgtFileStep);
298 } else if (arg == "-r" || arg == "--reinstall") {
300 return showHelpAndQuit();
302 _D("Installing package directly from directory");
303 m_installMode.command = InstallMode::Command::REINSTALL;
304 m_installMode.extension = InstallMode::ExtensionType::DIR;
305 m_packagePath = m_argv[2];
307 pkgmgrSignal->initialize(m_argc, m_argv);
308 pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
309 AddStep(&WrtInstaller::installStep);
310 } else if (arg == "-f" || arg == "--fota") {
311 // "path=8HPzsUYyNZ:op=install"
312 _D("Install & uninstall by fota");
314 return showHelpAndQuit();
316 std::string configuration = m_argv[2];
317 CommandParser::FotaOption option;
318 if (!CommandParser::FotaCommandParser(configuration, option)) {
319 return showHelpAndQuit();
322 if ((0 == option.operation.compare(Command::VALUE_INSTALL)) ||
323 (0 == option.operation.compare(Command::VALUE_UPGRADE)) ||
324 (0 == option.operation.compare(Command::VALUE_UPDATE))) {
325 _D("FOTA ... Installation");
326 m_name = option.pkgId;
328 std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath())
329 + "/" + option.pkgId;
330 _D("package id = %s", m_name.c_str());
331 _D("operation = %s", option.operation.c_str());
332 _D("package path = %s", m_packagePath.c_str());
334 m_installMode.installTime = InstallMode::InstallTime::FOTA;
335 m_installMode.rootPath = InstallMode::RootPath::RO;
336 m_installMode.extension = InstallMode::ExtensionType::DIR;
337 AddStep(&WrtInstaller::installStep);
338 } else if (0 == option.operation.compare(Command::VALUE_UNINSTALL)){
339 _D("FOTA ... Uninstallation");
340 m_name = option.pkgId;
341 _D("package id = %s", m_name.c_str());
342 AddStep(&WrtInstaller::uninstallPkgNameStep);
344 _E("Unknown operation : %s", option.operation.c_str());
345 return showHelpAndQuit();
347 } else if (arg == "-b" || arg == "--recovery") {
348 getRecoveryPackageId(m_name);
349 _D("m_name : %s", m_name.c_str());
351 if (!m_name.empty()) {
352 pkgmgrinfo_pkginfo_h handle = NULL;
353 if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
354 m_installMode.command = InstallMode::Command::RECOVERY;
355 m_installMode.extension = InstallMode::ExtensionType::DIR;
356 AddStep(&WrtInstaller::installStep);
358 _D("package id = %s", m_name.c_str());
359 AddStep(&WrtInstaller::uninstallPkgNameStep);
363 return showHelpAndQuit();
365 } else if (arg.find("backend") != std::string::npos) {
367 pkgmgrSignal->initialize(m_argc, m_argv);
368 PkgmgrSignal::RequestType reqType = pkgmgrSignal->getRequestedType();
369 pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
372 case PackageManager::PkgmgrSignal::RequestType::INSTALL:
373 m_packagePath = m_argv[4];
375 m_name = std::string(m_argv[6]);
379 if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
380 _D("Installing package directly from directory");
381 m_installMode.extension = InstallMode::ExtensionType::DIR;
383 _D("Installing from regular location");
384 m_installMode.extension = InstallMode::ExtensionType::WGT;
386 AddStep(&WrtInstaller::installStep);
388 case PackageManager::PkgmgrSignal::RequestType::UNINSTALL:
391 pkgmgrinfo_pkginfo_h handle = NULL;
392 bool preload = false;
394 bool removable = true;
396 char *cscPath = NULL;
398 if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
399 if (0 > pkgmgrinfo_pkginfo_is_preload(handle, &preload)) {
400 _E("Can't get package information : %s", m_name.c_str());
402 if (0 > pkgmgrinfo_pkginfo_is_system(handle, &system)) {
403 _E("Can't get package information : %s", m_name.c_str());
405 if (0 > pkgmgrinfo_pkginfo_is_removable(handle, &removable)) {
406 _E("Can't get package information : %s", m_name.c_str());
408 if (0 > pkgmgrinfo_pkginfo_is_update(handle, &update)) {
409 _E("Can't get package information about update : %s", m_name.c_str());
411 if (0 > pkgmgrinfo_pkginfo_get_csc_path(handle, &cscPath)) {
412 _E("Can't get package information about update : %s", m_name.c_str());
416 _D("preload app : %d", preload);
417 _D("system app : %d", system);
418 _D("removable app : %d", removable);
419 _D("update : %d", update);
420 _D("csc path : %s", cscPath);
422 if (preload && update) {
424 AddStep(&WrtInstaller::removeUpdateStep);
425 } else if (setInitialCSC(cscPath)) {
426 AddStep(&WrtInstaller::uninstallPkgNameStep);
427 AddStep(&WrtInstaller::installStep);
428 } else if (removable) {
429 AddStep(&WrtInstaller::uninstallPkgNameStep);
432 AddStep(&WrtInstaller::uninstallPkgNameStep);
434 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
437 case PackageManager::PkgmgrSignal::RequestType::REINSTALL:
438 m_packagePath = m_argv[4];
439 m_installMode.command = InstallMode::Command::REINSTALL;
440 m_installMode.extension = InstallMode::ExtensionType::DIR;
441 AddStep(&WrtInstaller::installStep);
444 _D("Not available type");
449 AddStep(&WrtInstaller::shutdownStep);
450 DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
452 WRTInstallerNS::NextStepEvent());
455 void WrtInstaller::OnReset(bundle* /*b*/)
460 void WrtInstaller::OnTerminate()
462 _D("Wrt Shutdown now");
465 power_unlock_state(POWER_STATE_SCREEN_OFF);
467 PluginUtils::unlockPluginInstallation(
468 m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
471 _D("DEINITIALIZING WRT INSTALLER...");
472 // Installer termination
473 CONTROLLER_POST_SYNC_EVENT(
474 Logic::InstallerController,
475 InstallerControllerEvents::
477 InstallerMainThreadSingleton::Instance().DetachDatabases();
478 I18n::DB::Interface::detachDatabase();
480 // This must be done after DetachDatabase
481 ValidationCore::VCoreDeinit();
483 // Global deinit check
484 _D("Cleanup libxml2 global values.");
486 } catch (const DPL::Exception& ex) {
487 _E("Internal Error during Shutdown:");
488 DPL::Exception::DisplayKnownException(ex);
493 void WrtInstaller::showHelpAndQuit()
495 printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/PATH]...\n"
496 "Operate with WebRuntime daemon: install, uninstall"
497 " and launch widgets.\n"
498 "Query list of installed widgets and setup up debugging support.\n"
500 "Exactly one option must be selected.\n"
501 "Mandatory arguments to long options are mandatory for short "
503 " -h, --help show this help\n"
504 " -p, --install-plugins install plugins\n"
506 "install or update widget package for given path\n"
508 "install or uninstall by CSC configuration \n"
509 " -un, --uninstall-name "
510 "uninstall widget for given package name\n"
511 " -up, --uninstall-packagepath "
512 "uninstall widget for given package file path\n"
514 "reinstall mode for sdk (this is NOT normal reinstallation/update)\n"
520 void WrtInstaller::showArguments()
523 "===========================================================\n");
524 fprintf(stderr, "# wrt-installer #\n");
525 fprintf(stderr, "# argc [%d]\n", m_argc);
526 for (int i = 0; i < m_argc; i++) {
527 fprintf(stderr, "# argv[%d] = [%s]\n", i, m_argv[i]);
530 "===========================================================\n");
532 _D("===========================================================");
533 _D("# wrt-installer #");
534 _D("# argc %d", m_argc);
535 for (int i = 0; i < m_argc; i++) {
536 _D("# argv[%d] = %s", i, m_argv[i]);
538 _D("===========================================================");
542 void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
547 _D("Wrt Shutdown now");
548 SwitchToStep(&WrtInstaller::shutdownStep);
549 DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
551 WRTInstallerNS::NextStepEvent());
553 _D("Quiting application");
558 void WrtInstaller::OnEventReceived(
559 const WRTInstallerNS::NextStepEvent& /*event*/)
561 _D("Executing next step");
565 void WrtInstaller::OnEventReceived(
566 const WRTInstallerNS::InstallPluginEvent& /*event*/)
568 PluginInstallerData* privateData = new PluginInstallerData;
569 privateData->wrtInstaller = this;
571 if (!(*m_pluginsPaths).empty()) {
572 privateData->pluginPath = (*m_pluginsPaths).front();
573 (*m_pluginsPaths).pop_front();
575 _D("INSTALL PLUGIN: %s", privateData->pluginPath.c_str());
576 //Private data for status callback
577 //Resource is free in pluginInstallFinishedCallback
578 InstallerCallbacksTranslate::PluginStatusCallbackStruct*
580 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
581 privateData, &staticWrtPluginInstallationCallback, &staticWrtPluginInstallProgressCb);
583 CONTROLLER_POST_EVENT(
584 Logic::InstallerController,
585 InstallerControllerEvents::InstallPluginEvent(
586 privateData->pluginPath,
587 PluginInstallerStruct(
588 InstallerCallbacksTranslate::
589 pluginInstallFinishedCallback,
590 InstallerCallbacksTranslate::
591 installProgressCallback, callbackStruct)));
597 void WrtInstaller::initStep()
600 _D("INITIALIZING WRT INSTALLER...");
602 // Touch InstallerController Singleton
603 InstallerMainThreadSingleton::Instance().TouchArchitecture();
607 makeStatusOfWrtInit(WRT_INSTALLER_ERROR_FATAL_ERROR);
611 // Initialize ValidationCore - this must be done before AttachDatabases
612 ValidationCore::VCoreInit(
613 std::string(GlobalConfig::GetFingerprintListFile()),
614 std::string(GlobalConfig::GetFingerprintListSchema()),
615 std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
617 InstallerMainThreadSingleton::Instance().AttachDatabases();
619 _D("Prepare libxml2 to work in multithreaded program.");
622 // Initialize Language Subtag registry
623 LanguageSubtagRstTreeSingleton::Instance().Initialize();
626 CONTROLLER_POST_SYNC_EVENT(
627 Logic::InstallerController,
628 InstallerControllerEvents::
631 makeStatusOfWrtInit(WRT_SUCCESS);
632 } catch (const DPL::Exception& ex) {
633 _E("Internal Error during Init:");
634 DPL::Exception::DisplayKnownException(ex);
635 makeStatusOfWrtInit(WRT_INSTALLER_ERROR_FATAL_ERROR);
639 void WrtInstaller::installStep()
641 std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
642 m_packagePath.c_str()));
644 if (InstallMode::InstallTime::PRELOAD == m_installMode.installTime) {
645 DPL::Log::OldStyleLogProvider *oldStyleProvider =
646 new DPL::Log::OldStyleLogProvider(false, false, false, true,
648 DPL::Log::LogSystemSingleton::Instance().AddProvider(oldStyleProvider);
651 std::string path = packagePath ? packagePath.get() : m_packagePath.c_str();
652 _D("INSTALL WIDGET: %s", path.c_str());
653 // Post installation event
654 CONTROLLER_POST_EVENT(
655 Logic::InstallerController,
656 InstallerControllerEvents::InstallWidgetEvent(
657 path, m_name.c_str(),
658 Jobs::WidgetInstall::WidgetInstallationStruct(
659 InstallerCallbacksTranslate::installFinishedCallback,
660 InstallerCallbacksTranslate::installProgressCallback,
661 new InstallerCallbacksTranslate::StatusCallbackStruct(
662 this, &staticWrtStatusCallback, (m_sendPkgSig)
663 ? &staticWrtInstallProgressCallback : NULL),
664 m_installMode, pkgmgrSignalInterface)));
667 void WrtInstaller::installPluginsStep()
669 _D("Installing plugins ...");
670 fprintf(stderr, "Installing plugins ...\n");
672 if (m_startupPluginInstallation) {
673 _D("Plugin installation started because new plugin package found");
674 } else if (!PluginUtils::lockPluginInstallation(
675 m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
677 _E("Failed to open plugin installation lock file"
678 " Plugins are currently installed by other process");
679 staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
684 std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
687 dir = opendir(PLUGIN_PATH.c_str());
693 _D("Plugin DIRECTORY IS %s", PLUGIN_PATH.c_str());
695 std::list<std::string> pluginsPaths;
696 struct dirent libdir;
697 struct dirent *result;
700 for (return_code = readdir_r(dir, &libdir, &result);
701 result != NULL && return_code == 0;
702 return_code = readdir_r(dir, &libdir, &result))
704 if (strcmp(libdir.d_name, ".") == 0 ||
705 strcmp(libdir.d_name, "..") == 0)
710 std::string path = PLUGIN_PATH;
712 path += libdir.d_name;
716 if (stat(path.c_str(), &tmp) == -1) {
717 _E("Failed to open file %s", path.c_str());
721 if (!S_ISDIR(tmp.st_mode)) {
722 _E("Not a directory %s", path.c_str());
726 pluginsPaths.push_back(path);
729 if (return_code != 0 || errno != 0) {
730 _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
733 //set nb of plugins to install
734 //this value indicate how many callbacks are expected
735 m_numPluginsToInstall = pluginsPaths.size();
736 _D("Plugins to install: %d", m_numPluginsToInstall);
737 m_pluginsPaths = pluginsPaths;
739 m_totalPlugins = m_numPluginsToInstall;
740 DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
741 ::PostEvent(WRTInstallerNS::InstallPluginEvent());
743 if (-1 == closedir(dir)) {
744 _E("Failed to close dir: %s with error: %s", PLUGIN_PATH.c_str(), DPL::GetErrnoString().c_str());
748 void WrtInstaller::uninstallPkgNameStep()
750 _D("Package name : %s", m_name.c_str());
752 _D("UNINSTALL WIDGET: %s", m_name.c_str());
753 // Post uninstallation event
754 CONTROLLER_POST_EVENT(
755 Logic::InstallerController,
756 InstallerControllerEvents::UninstallWidgetEvent(
758 WidgetUninstallationStruct(
759 InstallerCallbacksTranslate::uninstallFinishedCallback,
760 InstallerCallbacksTranslate::installProgressCallback,
761 new InstallerCallbacksTranslate::StatusCallbackStruct(
762 this, &staticWrtStatusCallback,
763 (m_sendPkgSig) ? &staticWrtUninstallProgressCallback : NULL),
764 pkgmgrSignalInterface)
769 void WrtInstaller::removeUpdateStep()
771 _D("This web app need to initialize preload app");
772 _D("Package name : %s", m_name.c_str());
774 _D("UNINSTALL WIDGET: %s", m_name.c_str());
775 // Post uninstallation event
776 CONTROLLER_POST_EVENT(
777 Logic::InstallerController,
778 InstallerControllerEvents::UninstallWidgetEvent(
780 WidgetUninstallationStruct(
781 InstallerCallbacksTranslate::uninstallFinishedCallback,
782 InstallerCallbacksTranslate::installProgressCallback,
783 new InstallerCallbacksTranslate::StatusCallbackStruct(
784 this, &staticWrtInitializeToPreloadCallback, (m_sendPkgSig)
785 ? &staticWrtUninstallProgressCallback : NULL),
786 pkgmgrSignalInterface
792 bool WrtInstaller::setInitialCSC(std::string cscPath)
794 _D("This web app need to initialize initial csc app");
795 _D("UNINSTALL WIDGET: %s", m_name.c_str());
796 _D("csc path: %s", cscPath.c_str());
798 m_installMode.installTime = InstallMode::InstallTime::CSC;
799 std::string configuration = cscPath;
801 CommandParser::CscOption option;
802 if (!CommandParser::CscCommandParser(configuration, option)) {
803 _E("Failure command parser");
807 if (0 == option.operation.compare(Command::VALUE_INSTALL)) {
808 m_installMode.extension = InstallMode::ExtensionType::WGT;
809 m_packagePath = option.path;
810 m_installMode.removable = option.removable;
811 m_installMode.cscPath = cscPath;
812 _D("operation = %s", option.operation.c_str());
813 _D("path = %s", m_packagePath.c_str());
814 _D("removable = %d", m_installMode.removable);
815 _D("csc Path = %s", m_installMode.cscPath.c_str());
817 _E("Unknown operation : %s", option.operation.c_str());
823 void WrtInstaller::unistallWgtFileStep()
825 _D("Uninstalling widget ...");
830 ConfigParserData configInfo;
833 std::unique_ptr<DPL::ZipInput> zipFile(
834 new DPL::ZipInput(m_packagePath));
835 std::unique_ptr<DPL::ZipInput::File> configFile;
838 // Open config.xml file
839 configFile.reset(zipFile->OpenFile(CONFIG_XML));
841 Catch(DPL::ZipInput::Exception::OpenFileFailed)
843 // Open config.xml file for hybrid
844 configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
848 DPL::BinaryQueue buffer;
849 DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
850 DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
851 DPL::Copy(&inputAdapter, &outputAdapter);
852 parser.Parse(&buffer,
854 new RootParser<WidgetParser>(configInfo,
855 DPL::FromUTF32String(
858 DPL::OptionalString pkgId = configInfo.tizenPkgId;
860 _D("Pkgid from packagePath : %ls", (*pkgId).c_str());
861 _D("UNINSTALL WIDGET: %s", DPL::ToUTF8String(*pkgId).c_str());
862 // Post uninstallation event
863 CONTROLLER_POST_EVENT(
864 Logic::InstallerController,
865 InstallerControllerEvents::UninstallWidgetEvent(
866 DPL::ToUTF8String(*pkgId),
867 WidgetUninstallationStruct(
868 InstallerCallbacksTranslate::uninstallFinishedCallback,
869 InstallerCallbacksTranslate::installProgressCallback,
870 new InstallerCallbacksTranslate::StatusCallbackStruct(
871 this, &staticWrtStatusCallback, !m_sendPkgSig
872 ? &staticWrtUninstallProgressCallback : NULL),
873 pkgmgrSignalInterface)
878 _E("Fail to uninstalling widget... ");
880 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
882 WRTInstallerNS::QuitEvent());
885 Catch(DPL::ZipInput::Exception::OpenFailed)
887 _E("Failed to open widget package");
888 printf("failed: widget package does not exist\n");
890 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
892 WRTInstallerNS::QuitEvent());
894 Catch(DPL::ZipInput::Exception::OpenFileFailed)
896 printf("failed: widget config file does not exist\n");
897 _E("Failed to open config.xml file");
899 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
901 WRTInstallerNS::QuitEvent());
903 Catch(ElementParser::Exception::ParseError)
905 printf("failed: can not parse config file\n");
906 _E("Failed to parse config.xml file");
908 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
910 WRTInstallerNS::QuitEvent());
912 Catch(DPL::Exception)
914 printf("Unknown DPL exception\n");
915 _E("Unknown DPL exception");
917 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
919 WRTInstallerNS::QuitEvent());
923 void WrtInstaller::shutdownStep()
925 _D("Closing Wrt connection ...");
928 _D("DEINITIALIZING WRT INSTALLER...");
929 // Installer termination
930 CONTROLLER_POST_SYNC_EVENT(
931 Logic::InstallerController,
932 InstallerControllerEvents::
935 InstallerMainThreadSingleton::Instance().DetachDatabases();
937 // This must be done after DetachDatabase
938 ValidationCore::VCoreDeinit();
940 // Global deinit check
941 _D("Cleanup libxml2 global values.");
943 } catch (const DPL::Exception& ex) {
944 _E("Internal Error during Shutdown:");
945 DPL::Exception::DisplayKnownException(ex);
947 m_initialized = false;
948 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
950 WRTInstallerNS::QuitEvent());
954 void WrtInstaller::makeStatusOfWrtInit(WrtErrStatus status)
956 if (status == WRT_SUCCESS) {
957 _D("Init succesfull");
958 m_initialized = true;
961 DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
962 ::PostEvent(WRTInstallerNS::NextStepEvent());
964 _E("Init unsuccesfull");
966 DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
968 WRTInstallerNS::QuitEvent());
972 void WrtInstaller::staticWrtInitializeToPreloadCallback(std::string tizenId, WrtErrStatus
973 status, void* userdata)
975 WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
978 std::string printMsg = "uninstallation";
980 if (WRT_SUCCESS != status) {
983 This->m_returnStatus = 1;
985 This->showErrorMsg(status, tizenId, printMsg);
987 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
988 ::PostEvent(WRTInstallerNS::QuitEvent());
991 mode.extension = InstallMode::ExtensionType::DIR;
992 mode.installTime = InstallMode::InstallTime::PRELOAD;
993 mode.rootPath = InstallMode::RootPath::RO;
994 std::string packagePath =
995 std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath())
996 + "/" + This->m_name;
998 if (InstallMode::InstallTime::PRELOAD == This->m_installMode.installTime) {
999 DPL::Log::OldStyleLogProvider *oldStyleProvider =
1000 new DPL::Log::OldStyleLogProvider(false, false, false, true,
1002 DPL::Log::LogSystemSingleton::Instance().AddProvider(oldStyleProvider);
1005 _D("INSTALL WIDGET: %s", packagePath.c_str());
1006 // Post installation event
1007 CONTROLLER_POST_EVENT(
1008 Logic::InstallerController,
1009 InstallerControllerEvents::InstallWidgetEvent(
1010 packagePath, tizenId.c_str(), Jobs::WidgetInstall::WidgetInstallationStruct(
1011 InstallerCallbacksTranslate::installFinishedCallback,
1012 InstallerCallbacksTranslate::installProgressCallback,
1013 new InstallerCallbacksTranslate::StatusCallbackStruct(
1014 This, &staticWrtInitPreloadStatusCallback, NULL),
1016 This->pkgmgrSignalInterface)));
1020 void WrtInstaller::staticWrtInitPreloadStatusCallback(std::string tizenId,
1021 WrtErrStatus status,
1024 WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1027 std::string printMsg = "initialization";
1029 if (WRT_SUCCESS != status) {
1032 This->m_returnStatus = status;
1034 This->showErrorMsg(status, tizenId, printMsg);
1036 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
1037 ::PostEvent(WRTInstallerNS::QuitEvent());
1040 "## wrt-installer : %s %s was successful.\n",
1043 _D("Status succesfull");
1044 This->m_returnStatus = 0;
1046 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
1048 ::PostEvent(WRTInstallerNS::NextStepEvent());
1052 void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
1053 WrtErrStatus status,
1056 WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1059 Step current = This->GetCurrentStep();
1060 std::string printMsg;
1062 if (current == &WrtInstaller::installStep) {
1063 printMsg = "installation";
1064 } else if (current == &WrtInstaller::uninstallPkgNameStep ||
1065 current == &WrtInstaller::unistallWgtFileStep)
1067 printMsg = "uninstallation";
1070 if (WRT_SUCCESS != status) {
1073 This->m_returnStatus = status;
1075 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
1076 ::PostEvent(WRTInstallerNS::QuitEvent());
1078 This->showErrorMsg(status, tizenId, printMsg);
1081 "## wrt-installer : %s %s was successful.\n",
1084 _D("Status succesfull");
1085 This->m_returnStatus = 0;
1087 if (This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD &&
1088 !This->m_packagePath.empty())
1090 _D("This widget is preloaded so it will be removed : %s", This->m_packagePath.c_str());
1091 if (!WrtUtilRemove(This->m_packagePath)) {
1092 _E("Failed to remove %s", This->m_packagePath.c_str());
1096 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
1098 ::PostEvent(WRTInstallerNS::NextStepEvent());
1102 void WrtInstaller::showErrorMsg(WrtErrStatus status, std::string tizenId,
1103 std::string printMsg)
1106 case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
1107 fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
1108 tizenId.c_str(), printMsg.c_str());
1111 case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
1112 fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
1113 tizenId.c_str(), printMsg.c_str());
1116 case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
1117 fprintf(stderr, "## wrt-installer : %s %s has failed - given"
1118 " version is lower than existing version\n",
1119 tizenId.c_str(), printMsg.c_str());
1122 case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
1123 fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
1124 " file doesn't find in package.\n",
1125 tizenId.c_str(), printMsg.c_str());
1128 case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
1129 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1130 "invalid manifestx.xml\n",
1131 tizenId.c_str(), printMsg.c_str());
1134 case WRT_INSTALLER_CONFIG_NOT_FOUND:
1135 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1136 "config.xml does not exist\n",
1137 tizenId.c_str(), printMsg.c_str());
1140 case WRT_INSTALLER_ERROR_CONFIG_INVALID:
1141 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1142 "invalid config.xml\n",
1143 tizenId.c_str(), printMsg.c_str());
1146 case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
1147 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1148 "signature doesn't exist in package.\n",
1149 tizenId.c_str(), printMsg.c_str());
1152 case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
1153 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1154 "invalid signature.\n",
1155 tizenId.c_str(), printMsg.c_str());
1158 case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
1159 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1160 "signature verification failed.\n",
1161 tizenId.c_str(), printMsg.c_str());
1164 case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
1165 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1166 "root certificate could not find.\n",
1167 tizenId.c_str(), printMsg.c_str());
1170 case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
1171 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1172 "invalid certification.\n",
1173 tizenId.c_str(), printMsg.c_str());
1176 case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
1177 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1178 "certificate chain verification failed.\n",
1179 tizenId.c_str(), printMsg.c_str());
1182 case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
1183 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1184 "certificate expired.\n",
1185 tizenId.c_str(), printMsg.c_str());
1188 case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
1189 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1190 "invalid privilege\n",
1191 tizenId.c_str(), printMsg.c_str());
1194 case WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION:
1195 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1196 "privilege level violation\n",
1197 tizenId.c_str(), printMsg.c_str());
1200 case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
1201 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1202 "menu icon could not find\n",
1203 tizenId.c_str(), printMsg.c_str());
1206 case WRT_INSTALLER_ERROR_FATAL_ERROR:
1207 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1209 tizenId.c_str(), printMsg.c_str());
1212 case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
1213 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1215 tizenId.c_str(), printMsg.c_str());
1218 case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
1219 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1221 tizenId.c_str(), printMsg.c_str());
1224 case WRT_INSTALLER_ERROR_ARGUMENT_INVALID:
1225 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1226 "invalid argument\n",
1227 tizenId.c_str(), printMsg.c_str());
1230 case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
1231 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1232 "package already installed\n",
1233 tizenId.c_str(), printMsg.c_str());
1236 case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
1237 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1238 "ace check failure\n",
1239 tizenId.c_str(), printMsg.c_str());
1242 case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
1243 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1244 "to create manifest failed\n",
1245 tizenId.c_str(), printMsg.c_str());
1248 case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
1249 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1250 "encryption of resource failed\n",
1251 tizenId.c_str(), printMsg.c_str());
1254 case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
1255 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1256 "installation of osp service failed\n",
1257 tizenId.c_str(), printMsg.c_str());
1260 case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
1261 fprintf(stderr, "## wrt-installer : %s %s has failed - "
1262 "widget uninstallation failed\n",
1263 tizenId.c_str(), printMsg.c_str());
1267 case WRT_INSTALLER_ERROR_UNKNOWN:
1268 fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
1269 tizenId.c_str(), printMsg.c_str());
1278 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
1283 PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
1285 WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
1287 std::string path = std::string(data->pluginPath);
1290 This->m_numPluginsToInstall--;
1291 _D("Plugins to install: %d", This->m_numPluginsToInstall);
1293 if (This->m_numPluginsToInstall < 1) {
1294 _D("All plugins installation completed");
1295 fprintf(stderr, "All plugins installation completed.\n");
1297 //remove installation request
1298 if (!PluginUtils::removeInstallationRequiredFlag()) {
1299 _D("Failed to remove file initializing plugin installation");
1303 if (!PluginUtils::unlockPluginInstallation(
1304 This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
1306 _D("Failed to remove installation lock");
1309 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
1310 ::PostEvent(WRTInstallerNS::NextStepEvent());
1312 This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
1313 InstallPluginEvent>::
1315 WRTInstallerNS::InstallPluginEvent());
1318 if (WRT_SUCCESS == status) {
1319 This->m_returnStatus = 0;
1321 "## wrt-installer : plugin installation successfull [%s]\n",
1323 _D("One plugin Installation succesfull: %s", path.c_str());
1328 _W("One of the plugins installation failed!: %s", path.c_str());
1331 case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
1332 _E("failed: plugin installation failed\n");
1335 case WRT_INSTALLER_ERROR_UNKNOWN:
1336 _E("failed: unknown error\n");
1344 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
1345 const char* description,
1348 PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
1350 std::string path = std::string(data->pluginPath);
1352 _D("Plugin Installation: %s progress: %2.0f description: %s", path.c_str(), percent, description);
1355 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
1356 const char* description,
1359 //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1360 _D(" progress: %2.0f description: %s", percent, description);
1362 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
1363 const char* description,
1366 //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
1367 _D(" progress: %2.0f description: %s", percent, description);
1370 void WrtInstaller::installNewPlugins()
1372 _D("Install new plugins");
1374 if (!PluginUtils::lockPluginInstallation(
1375 m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
1377 _D("Lock NOT created");
1381 if (!PluginUtils::checkPluginInstallationRequired()) {
1382 _D("Plugin installation not required");
1383 PluginUtils::unlockPluginInstallation(
1384 m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
1388 m_startupPluginInstallation = true;
1389 AddStep(&WrtInstaller::installPluginsStep);
1392 void WrtInstaller::getRecoveryPackageId(std::string &pkgId)
1394 _D("getRecoveryPackageId");
1395 std::string folderPath =
1396 std::string(WrtDB::GlobalConfig::GetTempInstallInfoPath()) + "/";
1398 DIR* dir = opendir(folderPath.c_str());
1403 struct dirent dEntry;
1404 struct dirent *dEntryResult;
1408 struct stat statInfo;
1409 return_code = readdir_r(dir, &dEntry, &dEntryResult);
1410 if (dEntryResult != NULL && return_code == 0) {
1411 std::string fileName = dEntry.d_name;
1412 std::string fullName = folderPath + "/" + fileName;
1414 if (stat(fullName.c_str(), &statInfo) != 0) {
1419 if (S_ISDIR(statInfo.st_mode)) {
1420 if (("." == fileName) || (".." == fileName)) {
1425 if (0 != unlink(fullName.c_str())) {
1426 _E("Fail to delete : %s", fullName.c_str());
1430 } while (dEntryResult != NULL && return_code == 0);
1435 void shell(const char* cmd) {
1439 _E("### %s ###", cmd);
1440 fp = popen(cmd, "r");
1442 _E("error: fp is NULL");
1444 while(fgets(buf, 256, fp) != NULL) {
1452 int main(int argc, char *argv[])
1454 UNHANDLED_EXCEPTION_HANDLER_BEGIN
1456 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_INSTALLER");
1458 // Output on stdout will be flushed after every newline character,
1459 // even if it is redirected to a pipe. This is useful for running
1460 // from a script and parsing output.
1461 // (Standard behavior of stdlib is to use full buffering when
1462 // redirected to a pipe, which means even after an end of line
1463 // the output may not be flushed).
1466 // Check and re-set the file open limitation
1468 if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
1469 _D("RLIMIT_NOFILE sft(%d)", rlim.rlim_cur);
1470 _D("RLIMIT_NOFILE hrd(%d)", rlim.rlim_max);
1472 if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
1473 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
1474 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
1475 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
1476 _E("setrlimit is fail!!");
1480 _E("getrlimit is fail!!");
1483 WrtInstaller app(argc, argv);
1484 int ret = app.Exec();
1485 // In FOTA environment, appcore will return -1 due to /tmp is read-only.
1491 _D("App returned: %d", ret);
1492 ret = app.getReturnStatus();
1493 _D("WrtInstaller returned: %d", ret);
1496 UNHANDLED_EXCEPTION_HANDLER_END