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