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