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