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