[Prevent] Handle unhandled exceptions in wrt-installer.
[framework/web/wrt-installer.git] / src / wrt-installer / wrt_installer.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /* @file    wrt_installer.cpp
17  * @version 1.0
18  * @brief   Implementation file for installer
19  */
20
21 #include "wrt_installer.h"
22 #include "plugin_utils.h"
23
24 #include <cstdlib>
25 #include <string>
26 #include <fstream>
27 #include <unistd.h>
28 #include <memory>
29 #include <sys/resource.h>
30 #include <dpl/optional.h>
31 #include <dpl/scoped_free.h>
32 #include <dpl/optional_typedefs.h>
33 #include <dpl/exception.h>
34 #include <dpl/sstream.h>
35 #include <vconf.h>
36 #include <dpl/wrt-dao-ro/global_config.h>
37 #include <dpl/wrt-dao-ro/config_parser_data.h>
38 #include <dpl/localization/localization_utils.h>
39 #include <dpl/optional_typedefs.h>
40 #include <dpl/string.h>
41 #include <dpl/abstract_waitable_input_adapter.h>
42 #include <dpl/abstract_waitable_output_adapter.h>
43 #include <dpl/zip_input.h>
44 #include <dpl/binary_queue.h>
45 #include <dpl/copy.h>
46 #include <dpl/errno_string.h>
47 #include <dpl/utils/wrt_global_settings.h>
48 #include "option_parser.h"
49 #include <parser_runner.h>
50 #include <widget_parser.h>
51 #include <root_parser.h>
52 #include <pkg-manager/pkgmgr_signal.h>
53
54 #define NOFILE_CNT_FOR_INSTALLER 9999
55
56 using namespace WrtDB;
57
58 namespace { // anonymous
59 const char AUL_ARG_KEY[] = "widget_arg";
60 const char * const PKGMGR_INSTALL_MSG = "Install widget";
61 const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
62
63 const double BASE_LAYOUT_W = 720.0f;
64 const double BASE_LAYOUT_H = 1280.0f;
65
66 const char * const CONFIG_XML = "config.xml";
67
68 struct free_deleter
69 {
70     void operator()(void* x) { free(x); }
71 };
72
73 struct PluginInstallerData
74 {
75     void* wrtInstaller;
76     std::string pluginPath;
77 };
78 } // namespace anonymous
79
80 WrtInstaller::WrtInstaller(int argc, char **argv) :
81     Application(argc, argv, "backend", false),
82     DPL::TaskDecl<WrtInstaller>(this),
83     m_packagePath(),
84     m_handle(-1),
85     m_initialized(false),
86     m_numPluginsToInstall(0),
87     m_totalPlugins(0),
88     m_returnStatus(-1),
89     m_installByPkgmgr(false),
90     m_quiet(true),
91     m_popup(NULL),
92     m_startupPluginInstallation(false),
93     m_preloadWidget(false)
94 {
95     Touch();
96     LogDebug("App Created");
97 }
98
99 WrtInstaller::~WrtInstaller()
100 {
101     LogDebug("App Finished");
102 }
103
104 void WrtInstaller::OnStop()
105 {
106     LogInfo("Stopping Dummy Client");
107 }
108
109 void WrtInstaller::OnCreate()
110 {
111     LogInfo("Creating DummyClient");
112
113     AddStep(&WrtInstaller::initStep);
114
115     std::string arg = m_argv[0];
116
117     if (arg.empty()) {
118         return showHelpAndQuit();
119     }
120
121     installNewPlugins();
122
123     if (arg.find("wrt-installer") != std::string::npos)
124     {
125         if (m_argc <= 1) {
126             return showHelpAndQuit();
127         }
128
129         arg = m_argv[1];
130         if (arg == "-h" || arg == "--help") {
131             if (m_argc != 2) {
132                 return showHelpAndQuit();
133             }
134
135             // Just show help
136             return showHelpAndQuit();
137         } else if (arg == "-p" || arg == "--install-plugins") {
138             if (m_argc != 2) {
139                 return showHelpAndQuit();
140             }
141             if (!m_startupPluginInstallation) {
142                 AddStep(&WrtInstaller::installPluginsStep);
143             } else {
144                 LogInfo("Plugin installation alredy started");
145             }
146         } else if (arg == "-i" || arg == "--install") {
147             if (m_argc != 3) {
148                 return showHelpAndQuit();
149             }
150
151             struct stat info;
152             if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
153                 LogInfo("Installing package directly from directory");
154                 m_installPolicy = WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL;
155             }
156             else
157             {
158                 LogInfo("Installing from regular location");
159                 m_installPolicy = WRT_WIM_POLICY_WAC;
160             }
161             m_packagePath = m_argv[2];
162             AddStep(&WrtInstaller::installStep);
163         } else if (arg == "-if" || arg == "--install-force") {
164             if (m_argc != 3) {
165                 return showHelpAndQuit();
166             }
167
168             m_packagePath = m_argv[2];
169             m_installPolicy = WRT_WIM_POLICY_FORCE_INSTALL;
170             AddStep(&WrtInstaller::installStep);
171         } else if (arg == "-il" || arg == "--install-preload") {
172             if (m_argc != 3) {
173                 return showHelpAndQuit();
174             }
175
176             m_packagePath = m_argv[2];
177             m_preloadWidget = true;
178             m_installPolicy = WRT_WIM_POLICY_WAC;
179             AddStep(&WrtInstaller::installStep);
180         } else if (arg == "-un" || arg == "--uninstall-name") {
181             if (m_argc != 3) {
182                 return showHelpAndQuit();
183             }
184             m_name = m_argv[2];
185             AddStep(&WrtInstaller::uninstallPkgNameStep);
186         } else if (arg == "-ug" || arg == "--uninstall-guid") {
187             if (m_argc != 3) {
188                 return showHelpAndQuit();
189             }
190             m_name = m_argv[2];
191             AddStep(&WrtInstaller::uninstallGuidStep);
192         } else if (arg == "-up" || arg == "--uninstall-packagepath") {
193             if (m_argc != 3) {
194                 return showHelpAndQuit();
195             }
196             m_packagePath = m_argv[2];
197             AddStep(&WrtInstaller::unistallWgtFileStep);
198         } else {
199             return showHelpAndQuit();
200         }
201
202     } else if (arg.find("backend") != std::string::npos) {
203         using namespace PackageManager;
204         m_installByPkgmgr = true;
205
206         PkgmgrSignalSingleton::Instance().initialize(m_argc, m_argv);
207         m_quiet = PkgmgrSignalSingleton::Instance().isNoPopupRequired();
208         LogDebug("backend m_quiet"<<m_quiet);
209
210         int reqType = PkgmgrSignalSingleton::Instance().getRequestedType();
211
212         switch (reqType) {
213             case PKGMGR_REQ_INSTALL:
214                 m_packagePath = m_argv[4];
215                 m_installPolicy = WRT_WIM_POLICY_WAC;
216                 AddStep(&WrtInstaller::installStep);
217                 break;
218             case PKGMGR_REQ_UNINSTALL:
219                 m_name = m_argv[4];
220                 AddStep(&WrtInstaller::uninstallPkgNameStep);
221                 break;
222             default:
223                 LogDebug("Not available type");
224                 break;
225         }
226     }
227
228     AddStep(&WrtInstaller::shutdownStep);
229     DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::PostEvent(
230         WRTInstallerNS::NextStepEvent());
231 }
232
233 void WrtInstaller::OnReset(bundle *b)
234 {
235     const char * bundledVal = bundle_get_val(b, AUL_ARG_KEY);
236     if (bundledVal != NULL) {
237         m_bundleValue = bundledVal;
238         LogInfo("Bundled value for (" << AUL_ARG_KEY << ") key received: " <<
239                 m_bundleValue);
240     }
241 }
242
243 int WrtInstaller::getReturnStatus() const
244 {
245     if (!m_returnStatus) {
246         return RE_SUCCESS;
247     } else {
248         return RE_FAIL;
249     }
250 }
251
252 void WrtInstaller::OnTerminate()
253 {
254     LogDebug("Wrt Shutdown now");
255     PluginUtils::unlockPluginInstallation();
256     if (m_initialized) {
257         wrt_installer_shutdown();
258     }
259     delete m_popup;
260 }
261
262 void WrtInstaller::showHelpAndQuit()
263 {
264     printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/GUID/PATH]...\n"
265            "Operate with WebRuntime daemon: install, uninstall"
266            " and launch widgets.\n"
267            "Query list of installed widgets and setup up debugging support.\n"
268            "\n"
269            "Exactly one option must be selected.\n"
270            "Mandatory arguments to long options are mandatory for short "
271            "options too.\n"
272            "  -h,    --help                                 show this help\n"
273            "  -p,    --install-plugins                      install plugins\n"
274            "  -i,    --install                              "
275            "install or update widget package for given path\n"
276            "  -if,   --install-force                        "
277            "install forcibly widget package for given path\n"
278            "  -un,   --uninstall-name                       "
279            "uninstall widget for given package name\n"
280            "  -ug,   --uninstall-guid                       "
281            "uninstall widget for given Global Unique IDentifier\n"
282            "  -up,   --uninstall-packagepath                "
283            "uninstall widget for given package file path\n"
284            "\n");
285
286     Quit();
287 }
288
289 void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
290 {
291     LogDebug("Quiting");
292
293     if (m_initialized) {
294         LogDebug("Wrt Shutdown now");
295         SwitchToStep(&WrtInstaller::shutdownStep);
296         DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::PostEvent(
297             WRTInstallerNS::NextStepEvent());
298     } else {
299         LogDebug("Quiting application");
300         return Quit();
301     }
302 }
303
304 void WrtInstaller::OnEventReceived(
305     const WRTInstallerNS::NextStepEvent& /*event*/)
306 {
307     LogDebug("Executing next step");
308     NextStep();
309 }
310
311 void WrtInstaller::OnEventReceived(
312     const WRTInstallerNS::InstallPluginEvent& /*event*/)
313 {
314     PluginInstallerData* privateData = new PluginInstallerData;
315     privateData->wrtInstaller = this;
316
317     if (!(*m_pluginsPaths).empty()) {
318         privateData->pluginPath = (*m_pluginsPaths).front();
319         (*m_pluginsPaths).pop_front();
320
321         wrt_install_plugin(privateData->pluginPath.c_str(),
322                 static_cast<void*>(privateData),
323                 &staticWrtPluginInstallationCallback,
324                 &staticWrtPluginInstallProgressCb);
325     } else {
326         delete privateData;
327     }
328 }
329
330 void WrtInstaller::initStep()
331 {
332     wrt_installer_init(this, staticWrtInitCallback);
333 }
334
335 void WrtInstaller::installStep()
336 {
337     LogDebug("Installing widget ...");
338     std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
339             m_packagePath.c_str()));
340
341     wrt_install_widget(packagePath ? packagePath.get() : m_packagePath.c_str(),
342                        this, &staticWrtStatusCallback,
343                        (!m_quiet || m_installByPkgmgr)
344                        ? &staticWrtInstallProgressCallback : NULL,
345                        m_installPolicy,
346                        m_quiet,
347                        m_preloadWidget);
348 }
349
350 void WrtInstaller::installPluginsStep()
351 {
352     LogDebug("Installing plugins ...");
353
354     if (m_startupPluginInstallation) {
355         LogInfo("Plugin installation started because new plugin package found");
356     } else if (!PluginUtils::lockPluginInstallation()) {
357         LogError("Failed to open plugin installation lock file"
358                 " Plugins are currently installed by other process");
359         staticWrtPluginInstallationCallback(WRT_PLUGIN_INSTALLER_ERROR_LOCK,
360                 this);
361         return;
362     }
363
364     std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
365
366     DIR *dir;
367     dir = opendir(PLUGIN_PATH.c_str());
368
369     if (!dir) {
370         return;
371     }
372
373     LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
374     struct dirent* libdir;
375
376     errno = 0;
377
378     std::list<std::string> pluginsPaths;
379
380     while ((libdir = readdir(dir)) != 0) {
381         if (strcmp(libdir->d_name, ".") == 0 ||
382             strcmp(libdir->d_name, "..") == 0)
383         {
384             continue;
385         }
386
387         std::string path = PLUGIN_PATH;
388         path += "/";
389         path += libdir->d_name;
390
391         struct stat tmp;
392
393         if (stat(path.c_str(), &tmp) == -1) {
394             LogError("Failed to open file" << path);
395             continue;
396         }
397
398         if (!S_ISDIR(tmp.st_mode)) {
399             LogError("Not a directory" << path);
400             continue;
401         }
402
403         pluginsPaths.push_back(path);
404     }
405
406     //set nb of plugins to install
407     //this value indicate how many callbacks are expected
408     m_numPluginsToInstall = pluginsPaths.size();
409     LogInfo("Plugins to install: " << m_numPluginsToInstall);
410     m_pluginsPaths = pluginsPaths;
411
412     m_totalPlugins = m_numPluginsToInstall;
413     DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
414         ::PostEvent(WRTInstallerNS::InstallPluginEvent());
415
416     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
417         LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
418                 << DPL::GetErrnoString());
419     }
420 }
421
422 void WrtInstaller::uninstallPkgNameStep()
423 {
424     LogDebug("Uninstalling widget ...");
425     LogDebug("Package name : " << m_name);
426     wrt_uninstall_widget(m_name.c_str(), this, &staticWrtStatusCallback,
427             (!m_quiet || m_installByPkgmgr)
428             ? &staticWrtUninstallProgressCallback : NULL);
429 }
430
431 void WrtInstaller::uninstallGuidStep()
432 {
433     LogDebug("Uninstalling widget ...");
434     std::string pkgname;
435     WrtErrStatus status = wrt_get_widget_by_guid(pkgname, m_name);
436     if (status == WRT_SUCCESS) {
437         LogDebug("Guid : " << m_name);
438         wrt_uninstall_widget(pkgname.c_str(), this, &staticWrtStatusCallback,
439                 !m_quiet ? &staticWrtUninstallProgressCallback : NULL);
440     } else {
441         printf("failed: can not uninstall widget\n");
442         LogError("Fail to uninstalling widget... ");
443         m_returnStatus = -1;
444         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
445             WRTInstallerNS::QuitEvent());
446     }
447 }
448
449 void WrtInstaller::unistallWgtFileStep()
450 {
451     LogDebug("Uninstalling widget ...");
452
453     Try {
454         // Parse config
455         ParserRunner parser;
456         ConfigParserData configInfo;
457
458         // Open zip file
459         std::unique_ptr<DPL::ZipInput> zipFile(
460                 new DPL::ZipInput(m_packagePath));
461
462         // Open config.xml file
463         std::unique_ptr<DPL::ZipInput::File> configFile(
464                 zipFile->OpenFile(CONFIG_XML));
465
466         // Extract config
467         DPL::BinaryQueue buffer;
468         DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
469         DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
470         DPL::Copy(&inputAdapter, &outputAdapter);
471         parser.Parse(&buffer,
472                 ElementParserPtr(
473                     new RootParser<WidgetParser>(configInfo,
474                         DPL::FromUTF32String(
475                             L"widget"))));
476
477         DPL::OptionalString widgetGUID = configInfo.widget_id;
478
479         std::string guid = DPL::ToUTF8String(*widgetGUID);
480
481         std::string pkgname;
482         WrtErrStatus status = wrt_get_widget_by_guid(pkgname, guid);
483         if (status == WRT_SUCCESS) {
484             LogDebug("Pkgname from packagePath : " << pkgname);
485             wrt_uninstall_widget(pkgname.c_str(), this, &staticWrtStatusCallback,
486                     !m_quiet ? &staticWrtUninstallProgressCallback : NULL);
487         } else {
488             LogError("Fail to uninstalling widget... ");
489             m_returnStatus = -1;
490             DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
491                     WRTInstallerNS::QuitEvent());
492         }
493     }
494     Catch(DPL::ZipInput::Exception::OpenFailed)
495     {
496         LogError("Failed to open widget package");
497         printf("failed: widget package does not exist\n");
498         m_returnStatus = -1;
499         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
500                 WRTInstallerNS::QuitEvent());
501     }
502     Catch(DPL::ZipInput::Exception::OpenFileFailed)
503     {
504         printf("failed: widget config file does not exist\n");
505         LogError("Failed to open config.xml file");
506         m_returnStatus = -1;
507         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
508                 WRTInstallerNS::QuitEvent());
509     }
510     Catch(ElementParser::Exception::ParseError)
511     {
512         printf("failed: can not parse config file\n");
513         LogError("Failed to parse config.xml file");
514         m_returnStatus = -1;
515         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
516                 WRTInstallerNS::QuitEvent());
517     }
518 }
519
520 void WrtInstaller::shutdownStep()
521 {
522     LogDebug("Closing Wrt connection ...");
523     if (m_initialized) {
524         wrt_installer_shutdown();
525         m_initialized = false;
526         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
527             WRTInstallerNS::QuitEvent());
528     }
529 }
530
531 void WrtInstaller::staticWrtInitCallback(WrtErrStatus status,
532                                       void* userdata)
533 {
534     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
535     Assert(This);
536
537     if (status == WRT_SUCCESS) {
538         LogDebug("Init succesfull");
539         This->m_initialized = true;
540         This->m_returnStatus = 0;
541
542         if (This->popupsEnabled()) {
543             This->m_popup = new InstallerPopup;
544             This->m_popup->init();
545         }
546
547         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
548             ::PostEvent(WRTInstallerNS::NextStepEvent());
549     } else {
550         LogError("Init unsuccesfull");
551         This->m_returnStatus = -1;
552         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent(
553             WRTInstallerNS::QuitEvent());
554     }
555 }
556
557 void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
558                                            WrtErrStatus status,
559                                            void* userdata)
560 {
561     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
562     Assert(This);
563
564     Step current = This->GetCurrentStep();
565     DPL::String resultMsg;
566     std::string printMsg;
567
568     if (current == &WrtInstaller::installStep)
569     {
570         resultMsg = DPL::FromUTF8String(PKGMGR_INSTALL_MSG);
571         printMsg = "installed";
572     } else if (current == &WrtInstaller::uninstallPkgNameStep ||
573             current == &WrtInstaller::uninstallGuidStep ||
574             current == &WrtInstaller::unistallWgtFileStep)
575     {
576         resultMsg = DPL::FromUTF8String(PKGMGR_UNINSTALL_MSG);
577         printMsg = "uninstalled";
578     }
579
580     if (WRT_SUCCESS != status) {
581         // Failure
582         LogError("Step failed");
583         This->m_returnStatus = -1;
584
585         if (This->popupsEnabled()) {
586             resultMsg +=  L" : " + DPL::FromUTF8String(PKGMGR_END_FAILURE);
587             This->m_popup->showPopup(This, resultMsg, failResultCallback);
588         } else {
589             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
590                 ::PostEvent(WRTInstallerNS::QuitEvent());
591         }
592
593         switch (status) {
594             case WRT_INSTALLER_ERROR_INVALID_WIDGET_PACKAGE:
595                 This->m_returnStatus = 1; //this status is specific
596                 printf("failed: invalid widget package\n");
597                 break;
598
599             case WRT_INSTALLER_ERROR_WIDGET_DOES_NOT_EXIST:
600                 printf("failed: widget package does not exist\n");
601                 break;
602
603             case WRT_INSTALLER_ERROR_ALREADY_UNINSTALLING:
604                 printf("failed: already uninstalling\n");
605                 break;
606
607             case WRT_INSTALLER_ERROR_OUT_OUT_DISK_SPACE:
608                 printf("failed: out of disk space\n");
609                 break;
610
611             case WRT_INSTALLER_ERROR_INVALID_CERTIFICATE:
612                 printf("failed: invalid certificate\n");
613                 break;
614
615             case WRT_INSTALLER_ERROR_ALREADY_INSTALLED:
616                 printf("failed: already installed\n");
617                 break;
618
619             case WRT_INSTALLER_ERROR_INTERNAL:
620                 printf("failed: internal error\n");
621                 break;
622
623             case WRT_INSTALLER_ERROR_NOT_ALLOWED:
624                 printf("failed: installation or update not allowed; invalid"
625                        " mode\n");
626                 break;
627
628             case WRT_INSTALLER_ERROR_DEFERRED:
629                 printf("deferred: widget update will continue after the widget"
630                        " has been stopped\n");
631                 break;
632
633             case WRT_INSTALLER_ERROR_DATABASE_FAILURE:
634                 printf("failed: database failure\n");
635                 break;
636
637             case WRT_INSTALLER_ERROR_OSPSVC:
638                 printf("failed: during installation or uninstallation osp service\n");
639                 break;
640
641             case WRT_INSTALLER_ERROR_UNKNOWN:
642                 printf("failed: unknown error\n");
643                 break;
644
645             default:
646                 break;
647         }
648     } else {
649
650         printf("%s : %s\n", printMsg.c_str(), tizenId.c_str());
651         LogDebug("Status succesfull");
652         This->m_returnStatus = 0;
653         resultMsg +=  L" : " + DPL::FromUTF8String(PKGMGR_END_SUCCESS);
654
655         if (This->popupsEnabled()) {
656             This->m_popup->showPopup(This, resultMsg, showResultCallback);
657         } else {
658             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
659                 ::PostEvent(WRTInstallerNS::NextStepEvent());
660         }
661     }
662 }
663
664 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
665                                                     void* userdata)
666 {
667     Assert(userdata);
668
669     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
670
671     WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
672
673     std::string path = std::string(data->pluginPath);
674     delete data;
675
676     This->m_numPluginsToInstall--;
677     LogDebug("Plugins to install: " << This->m_numPluginsToInstall);
678
679     if (This->m_numPluginsToInstall < 1) {
680         LogDebug("All plugins installation completed");
681
682         //remove installation request
683         if (!PluginUtils::removeInstallationRequiredFlag()) {
684             LogInfo("Failed to remove file initializing plugin installation");
685         }
686
687         //remove lock file
688         if (!PluginUtils::unlockPluginInstallation()) {
689             LogInfo("Failed to remove installation lock");
690         }
691
692         if (This->popupsEnabled()) {
693             This->m_popup->init();
694             elm_progressbar_value_set(This->m_popup->m_progressbar, 100.0);
695             evas_object_show(This->m_popup->m_popup);
696         }
697
698         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
699             ::PostEvent(WRTInstallerNS::NextStepEvent());
700     } else {
701         if (This->popupsEnabled()) {
702             This->m_popup->init();
703             float percent = (This->m_totalPlugins - This->m_numPluginsToInstall)/(float)This->m_totalPlugins;
704             elm_progressbar_value_set(This->m_popup->m_progressbar, percent);
705             evas_object_show(This->m_popup->m_popup);
706         }
707
708         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>::PostEvent(
709                 WRTInstallerNS::InstallPluginEvent());
710     }
711
712     if (WRT_SUCCESS == status) {
713         This->m_returnStatus = 0;
714         LogDebug("One plugin Installation succesfull: " << path);
715         return;
716     }
717
718     // Failure
719     LogWarning("One of the plugins installation failed!: " << path);
720
721     if (WRT_PLUGIN_INSTALLER_ERROR_WAITING == status) {
722         LogInfo("Plugin installation is waiting for dependencies");
723     }
724
725     switch (status) {
726     case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
727         LogError("failed: wrong path to plugin directory\n");
728         break;
729
730     case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
731         LogError("failed: plugin metafile error\n");
732         break;
733
734     case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
735         LogError("failed: plugin already installed\n");
736         break;
737
738     case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
739         LogError("failed: plugin library: missing symbols or structures\n");
740         break;
741
742     case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
743         LogError("failed: unknown error\n");
744         break;
745
746     default:
747         break;
748     }
749 }
750
751 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
752                                                     const char* description,
753                                                     void* userdata)
754 {
755     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
756
757     std::string path = std::string(data->pluginPath);
758
759     LogInfo("Plugin Installation: " << path <<
760             " progress: " << percent <<
761             "description " << description);
762 }
763
764 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
765         const char* description, void* userdata)
766 {
767     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
768     std::stringstream percentStr;
769     LogInfo(" progress: " << percent <<
770             " description: " << description);
771
772     if (This->popupsEnabled()) {
773         This->m_popup->init();
774         elm_progressbar_value_set(This->m_popup->m_progressbar, percent/100.0);
775         evas_object_show(This->m_popup->m_popup);
776     }
777 }
778 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
779         const char* description, void* userdata)
780 {
781     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
782     std::stringstream percentStr;
783     LogInfo(" progress: " << percent <<
784             " description: " << description);
785
786     if (This->popupsEnabled()) {
787         This->m_popup->init();
788         elm_progressbar_value_set(This->m_popup->m_progressbar, percent/100.0);
789         evas_object_show(This->m_popup->m_popup);
790     }
791 }
792
793 WrtInstaller::InstallerPopup::InstallerPopup() :
794     m_win(NULL),
795     m_popup(NULL),
796     m_progressbar(NULL)
797 {
798 }
799
800 WrtInstaller::InstallerPopup::~InstallerPopup()
801 {
802     LogDebug("App Finished");
803 }
804
805 void WrtInstaller::InstallerPopup::init()
806 {
807     LogDebug("Window Init");
808
809     if (m_win == NULL) {
810         // create window
811         m_win = createWin("wrt-installer");
812
813         // create popup
814         m_popup = elm_popup_add(m_win);
815
816         // create progressbar
817         m_progressbar = elm_progressbar_add(m_popup);
818         elm_object_style_set(m_progressbar, "list_progress");
819         elm_progressbar_horizontal_set(m_progressbar, EINA_TRUE);
820         evas_object_size_hint_align_set(m_progressbar, EVAS_HINT_FILL,
821             EVAS_HINT_FILL);
822         evas_object_size_hint_weight_set(m_progressbar, EVAS_HINT_EXPAND,
823             EVAS_HINT_EXPAND);
824         elm_object_content_set(m_popup, m_progressbar);
825         elm_progressbar_value_set(m_progressbar, 0.0);
826         evas_object_show(m_progressbar);
827
828         evas_object_show(m_popup);
829         evas_object_show(m_win);
830     }
831 }
832
833 Evas_Object* WrtInstaller::InstallerPopup::createWin(const char *name)
834 {
835     Evas_Object *win;
836     win = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC);
837
838     int w, h;
839     if(!win)
840         return NULL;
841
842     elm_win_alpha_set(win, EINA_TRUE);
843     elm_win_title_set(win, name);
844     elm_win_borderless_set(win, EINA_TRUE);
845     elm_win_raise(win);
846
847     ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
848     evas_object_resize(win, w, h);
849     return win;
850 }
851
852 void WrtInstaller::InstallerPopup::showPopup(void* userdata,
853                                              const DPL::String& pkgMsg,
854                                              ShowResultCallback callback)
855 {
856     Evas_Object *btn;
857
858
859     LogDebug("Result Popup Created");
860     evas_object_del(m_popup);
861     m_popup = NULL;
862
863     m_popup = elm_popup_add(m_win);
864     if (!m_popup)
865         return;
866
867     btn = elm_button_add(m_popup);
868     if (!btn) {
869         evas_object_del(m_popup);
870         return;
871     }
872     elm_object_text_set(btn, "OK");
873     evas_object_smart_callback_add(btn, "clicked", callback, userdata);
874     elm_object_part_content_set(m_popup, "button1", btn);
875     elm_object_part_text_set(m_popup, "title,text", "RESULT");
876     elm_object_text_set(m_popup, DPL::ToUTF8String(pkgMsg).c_str());
877
878     evas_object_show(m_popup);
879     evas_object_show(m_win);
880
881 }
882
883 void WrtInstaller::showResultCallback(void *data, Evas_Object* /*obj*/,
884                                       void* /*event_info*/)
885 {
886     WrtInstaller *This = static_cast<WrtInstaller*>(data);
887     Assert(This);
888
889     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
890         ::PostEvent(WRTInstallerNS::NextStepEvent());
891 }
892
893 void WrtInstaller::failResultCallback(void *data, Evas_Object* /*obj*/,
894                                       void* /*event_info*/)
895 {
896     WrtInstaller *This = static_cast<WrtInstaller*>(data);
897     Assert(This);
898
899     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
900         ::PostEvent(WRTInstallerNS::QuitEvent());
901 }
902
903 void WrtInstaller::installNewPlugins()
904 {
905     LogDebug("Install new plugins");
906
907     if (!PluginUtils::lockPluginInstallation()) {
908         LogInfo("Lock NOT created");
909         return;
910     }
911
912     if (!PluginUtils::checkPluginInstallationRequired()) {
913         LogDebug("Plugin installation not required");
914         PluginUtils::unlockPluginInstallation();
915         return;
916     }
917
918     m_startupPluginInstallation = true;
919     AddStep(&WrtInstaller::installPluginsStep);
920 }
921
922 bool WrtInstaller::popupsEnabled() const
923 {
924     return !m_quiet && !GlobalSettings::PopupsTestModeEnabled();
925 }
926
927 int main(int argc, char *argv[])
928 {
929     UNHANDLED_EXCEPTION_HANDLER_BEGIN
930     {
931         // Output on stdout will be flushed after every newline character,
932         // even if it is redirected to a pipe. This is useful for running
933         // from a script and parsing output.
934         // (Standard behavior of stdlib is to use full buffering when
935         // redirected to a pipe, which means even after an end of line
936         // the output may not be flushed).
937         setlinebuf(stdout);
938
939         // Check and re-set the file open limitation
940         struct rlimit rlim;
941         if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
942             LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")" );
943             LogDebug("RLIMIT_NOFILE hrd(" << rlim.rlim_max << ")" );
944
945             if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
946                 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
947                 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
948                 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
949                     LogError("setrlimit is fail!!");
950                 }
951             }
952         } else {
953             LogError("getrlimit is fail!!");
954         }
955
956         // set evas backend type for emulator
957         // popup isn't showed in the emulator,
958         // if backend isn't set to SW backend
959         if (GlobalSettings::IsEmulator()) {
960             if (setenv("ELM_ENGINE", "x11", 1)) {
961                 LogDebug("Enable backend");
962             }
963         }
964
965         WrtInstaller app(argc, argv);
966         int ret = app.Exec();
967         LogDebug("App returned: " << ret);
968         ret = app.getReturnStatus();
969         LogDebug("WrtInstaller returned: " << ret);
970         return ret;
971     }
972     UNHANDLED_EXCEPTION_HANDLER_END
973 }