72c689e8b0930c6ad5be889132fca3cbe1de78fe
[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 #define NOFILE_CNT_FOR_INSTALLER 9999
54
55 using namespace WrtDB;
56
57 namespace { // anonymous
58 const char AUL_ARG_KEY[] = "widget_arg";
59 const char * const PKGMGR_INSTALL_MSG = "Install widget";
60 const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
61
62 const double BASE_LAYOUT_W = 720.0f;
63 const double BASE_LAYOUT_H = 1280.0f;
64
65 const char * const CONFIG_XML = "config.xml";
66 const char * const HYBRID_CONFIG_XML = "res/wgt/config.xml";
67
68 struct free_deleter
69 {
70     void operator()(void* x)
71     {
72         free(x);
73     }
74 };
75
76 struct PluginInstallerData
77 {
78     void* wrtInstaller;
79     std::string pluginPath;
80 };
81 } // namespace anonymous
82
83 WrtInstaller::WrtInstaller(int argc, char **argv) :
84     Application(argc, argv, "backend", false),
85     DPL::TaskDecl<WrtInstaller>(this),
86     m_installPolicy(WRT_WIM_NOT_INSTALLED),
87     m_packagePath(),
88     m_handle(-1),
89     m_initialized(false),
90     m_numPluginsToInstall(0),
91     m_totalPlugins(0),
92     m_returnStatus(-1),
93     m_installByPkgmgr(false),
94     m_quiet(true),
95     m_popup(NULL),
96     m_startupPluginInstallation(false),
97     m_preloadWidget(false)
98 {
99     Touch();
100     LogDebug("App Created");
101 }
102
103 WrtInstaller::~WrtInstaller()
104 {
105     LogDebug("App Finished");
106 }
107
108 void WrtInstaller::OnStop()
109 {
110     LogInfo("Stopping Dummy Client");
111 }
112
113 void WrtInstaller::OnCreate()
114 {
115     LogInfo("Creating DummyClient");
116     fprintf(stderr,
117             "===========================================================\n");
118     fprintf(stderr, "# wrt-installer #\n");
119     fprintf(stderr, "# argc [%d]\n", m_argc);
120     fprintf(stderr, "# argv[0] = [%s]\n", m_argv[0]);
121     fprintf(stderr, "# argv[1] = [%s]\n", m_argv[1]);
122     fprintf(stderr, "# argv[2] = [%s]\n", m_argv[2]);
123     fprintf(stderr,
124             "===========================================================\n");
125
126     AddStep(&WrtInstaller::initStep);
127
128     std::string arg = m_argv[0];
129
130     pkgmgrSignalInterface =
131         std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
132             std::shared_ptr<PackageManager::PkgmgrSignalDummy>(
133                 new PackageManager::PkgmgrSignalDummy()
134                 )
135             );
136
137     if (arg.empty()) {
138         return showHelpAndQuit();
139     }
140
141     installNewPlugins();
142
143     if (arg.find("wrt-installer") != std::string::npos) {
144         if (m_argc <= 1) {
145             return showHelpAndQuit();
146         }
147
148         arg = m_argv[1];
149         if (arg == "-h" || arg == "--help") {
150             if (m_argc != 2) {
151                 return showHelpAndQuit();
152             }
153
154             // Just show help
155             return showHelpAndQuit();
156         } else if (arg == "-p" || arg == "--install-plugins") {
157             if (m_argc != 2) {
158                 return showHelpAndQuit();
159             }
160             if (!m_startupPluginInstallation) {
161                 AddStep(&WrtInstaller::installPluginsStep);
162             } else {
163                 LogInfo("Plugin installation alredy started");
164             }
165         } else if (arg == "-i" || arg == "--install") {
166             if (m_argc != 3) {
167                 return showHelpAndQuit();
168             }
169
170             struct stat info;
171             if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
172                 LogInfo("Installing package directly from directory");
173                 m_installPolicy = WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL;
174             } else {
175                 LogInfo("Installing from regular location");
176                 m_installPolicy = WRT_WIM_POLICY_WAC;
177             }
178             m_packagePath = m_argv[2];
179             AddStep(&WrtInstaller::installStep);
180         } else if (arg == "-if" || arg == "--install-force") {
181             if (m_argc != 3) {
182                 return showHelpAndQuit();
183             }
184
185             m_packagePath = m_argv[2];
186             m_installPolicy = WRT_WIM_POLICY_FORCE_INSTALL;
187             AddStep(&WrtInstaller::installStep);
188         } else if (arg == "-il" || arg == "--install-preload") {
189             if (m_argc != 3) {
190                 return showHelpAndQuit();
191             }
192
193             m_packagePath = m_argv[2];
194             m_preloadWidget = true;
195             m_installPolicy = WRT_WIM_POLICY_WAC;
196             AddStep(&WrtInstaller::installStep);
197         } else if (arg == "-un" || arg == "--uninstall-name") {
198             if (m_argc != 3) {
199                 return showHelpAndQuit();
200             }
201             m_name = m_argv[2];
202             AddStep(&WrtInstaller::uninstallPkgNameStep);
203         } else if (arg == "-ug" || arg == "--uninstall-guid") {
204             if (m_argc != 3) {
205                 return showHelpAndQuit();
206             }
207             m_name = m_argv[2];
208             AddStep(&WrtInstaller::uninstallGuidStep);
209         } else if (arg == "-up" || arg == "--uninstall-packagepath") {
210             if (m_argc != 3) {
211                 return showHelpAndQuit();
212             }
213             m_packagePath = m_argv[2];
214             AddStep(&WrtInstaller::unistallWgtFileStep);
215         } else {
216             return showHelpAndQuit();
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>(
234                 pkgmgrSignal);
235         switch (reqType) {
236         case PKGMGR_REQ_INSTALL:
237             m_packagePath = m_argv[4];
238             struct stat info;
239             if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
240                 LogInfo("Installing package directly from directory");
241                 m_installPolicy = WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL;
242             } else {
243                 LogInfo("Installing from regular location");
244                 m_installPolicy = WRT_WIM_POLICY_WAC;
245             }
246             AddStep(&WrtInstaller::installStep);
247             break;
248         case PKGMGR_REQ_UNINSTALL:
249             m_name = m_argv[4];
250             AddStep(&WrtInstaller::uninstallPkgNameStep);
251             break;
252         default:
253             LogDebug("Not available type");
254             break;
255         }
256     }
257
258     AddStep(&WrtInstaller::shutdownStep);
259     DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
260         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>::
328             PostEvent(
329             WRTInstallerNS::NextStepEvent());
330     } else {
331         LogDebug("Quiting application");
332         return Quit();
333     }
334 }
335
336 void WrtInstaller::OnEventReceived(
337     const WRTInstallerNS::NextStepEvent& /*event*/)
338 {
339     LogDebug("Executing next step");
340     NextStep();
341 }
342
343 void WrtInstaller::OnEventReceived(
344     const WRTInstallerNS::InstallPluginEvent& /*event*/)
345 {
346     PluginInstallerData* privateData = new PluginInstallerData;
347     privateData->wrtInstaller = this;
348
349     if (!(*m_pluginsPaths).empty()) {
350         privateData->pluginPath = (*m_pluginsPaths).front();
351         (*m_pluginsPaths).pop_front();
352
353         wrt_install_plugin(privateData->pluginPath.c_str(),
354                            static_cast<void*>(privateData),
355                            &staticWrtPluginInstallationCallback,
356                            &staticWrtPluginInstallProgressCb);
357     } else {
358         delete privateData;
359     }
360 }
361
362 void WrtInstaller::initStep()
363 {
364     wrt_installer_init(this, staticWrtInitCallback);
365 }
366
367 void WrtInstaller::installStep()
368 {
369     LogDebug("Installing widget ...");
370     std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
371                                                         m_packagePath.c_str()));
372
373     wrt_install_widget(packagePath ? packagePath.get() : m_packagePath.c_str(),
374                        this, &staticWrtStatusCallback,
375                        (!m_quiet || m_installByPkgmgr)
376                        ? &staticWrtInstallProgressCallback : NULL,
377                        m_installPolicy,
378                        m_quiet,
379                        m_preloadWidget,
380                        pkgmgrSignalInterface);
381 }
382
383 void WrtInstaller::installPluginsStep()
384 {
385     LogDebug("Installing plugins ...");
386     fprintf(stderr, "Installing plugins ...\n");
387
388     if (m_startupPluginInstallation) {
389         LogInfo("Plugin installation started because new plugin package found");
390     } else if (!PluginUtils::lockPluginInstallation()) {
391         LogError("Failed to open plugin installation lock file"
392                  " Plugins are currently installed by other process");
393         staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
394                                             this);
395         return;
396     }
397
398     std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
399
400     DIR *dir;
401     dir = opendir(PLUGIN_PATH.c_str());
402
403     if (!dir) {
404         return;
405     }
406
407     LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
408
409     std::list<std::string> pluginsPaths;
410     struct dirent libdir;
411     struct dirent *result;
412     int return_code;
413     errno = 0;
414     for (return_code = readdir_r(dir, &libdir, &result);
415             result != NULL && return_code == 0;
416             return_code = readdir_r(dir, &libdir, &result))
417     {
418         if (strcmp(libdir.d_name, ".") == 0 ||
419             strcmp(libdir.d_name, "..") == 0)
420         {
421             continue;
422         }
423
424         std::string path = PLUGIN_PATH;
425         path += "/";
426         path += libdir.d_name;
427
428         struct stat tmp;
429
430         if (stat(path.c_str(), &tmp) == -1) {
431             LogError("Failed to open file" << path);
432             continue;
433         }
434
435         if (!S_ISDIR(tmp.st_mode)) {
436             LogError("Not a directory" << path);
437             continue;
438         }
439
440         pluginsPaths.push_back(path);
441     }
442
443     if (return_code != 0 || errno != 0) {
444         LogError("readdir_r() failed with " << DPL::GetErrnoString());
445     }
446
447     //set nb of plugins to install
448     //this value indicate how many callbacks are expected
449     m_numPluginsToInstall = pluginsPaths.size();
450     LogInfo("Plugins to install: " << m_numPluginsToInstall);
451     m_pluginsPaths = pluginsPaths;
452
453     m_totalPlugins = m_numPluginsToInstall;
454     DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
455         ::PostEvent(WRTInstallerNS::InstallPluginEvent());
456
457     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
458         LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
459                                          << DPL::GetErrnoString());
460     }
461 }
462
463 void WrtInstaller::uninstallPkgNameStep()
464 {
465     LogDebug("Uninstalling widget ...");
466     LogDebug("Package name : " << m_name);
467     wrt_uninstall_widget(m_name.c_str(), this, &staticWrtStatusCallback,
468                          (!m_quiet || m_installByPkgmgr)
469                          ? &staticWrtUninstallProgressCallback : NULL,
470                          pkgmgrSignalInterface);
471 }
472
473 void WrtInstaller::uninstallGuidStep()
474 {
475     LogDebug("Uninstalling widget ...");
476     std::string appid;
477     WrtErrStatus status = wrt_get_widget_by_guid(appid, m_name);
478     if (status == WRT_SUCCESS) {
479         LogDebug("Guid : " << m_name);
480         wrt_uninstall_widget(
481             appid.c_str(), this, &staticWrtStatusCallback,
482             !m_quiet ? &staticWrtUninstallProgressCallback :
483             NULL,
484             pkgmgrSignalInterface);
485     } else {
486         printf("failed: can not uninstall widget\n");
487         LogError("Fail to uninstalling widget... ");
488         m_returnStatus = -1;
489         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
490             PostEvent(
491             WRTInstallerNS::QuitEvent());
492     }
493 }
494
495 void WrtInstaller::unistallWgtFileStep()
496 {
497     LogDebug("Uninstalling widget ...");
498
499     Try {
500         // Parse config
501         ParserRunner parser;
502         ConfigParserData configInfo;
503
504         // Open zip file
505         std::unique_ptr<DPL::ZipInput> zipFile(
506             new DPL::ZipInput(m_packagePath));
507         std::unique_ptr<DPL::ZipInput::File> configFile;
508
509         Try {
510             // Open config.xml file
511             configFile.reset(zipFile->OpenFile(CONFIG_XML));
512         }
513         Catch(DPL::ZipInput::Exception::OpenFileFailed)
514         {
515             // Open config.xml file for hybrid
516             configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
517         }
518
519         // Extract config
520         DPL::BinaryQueue buffer;
521         DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
522         DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
523         DPL::Copy(&inputAdapter, &outputAdapter);
524         parser.Parse(&buffer,
525                      ElementParserPtr(
526                          new RootParser<WidgetParser>(configInfo,
527                                                       DPL::FromUTF32String(
528                                                           L"widget"))));
529
530         DPL::OptionalString pkgId = configInfo.tizenPkgId;
531         if (!pkgId.IsNull()) {
532             LogDebug("Pkgid from packagePath : " << pkgId);
533             wrt_uninstall_widget(
534                 DPL::ToUTF8String(*pkgId).c_str(), this, &staticWrtStatusCallback,
535                 !m_quiet ? &staticWrtUninstallProgressCallback
536                 : NULL,
537                 pkgmgrSignalInterface);
538         } else {
539             LogError("Fail to uninstalling widget... ");
540             m_returnStatus = -1;
541             DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
542                 PostEvent(
543                 WRTInstallerNS::QuitEvent());
544         }
545     }
546     Catch(DPL::ZipInput::Exception::OpenFailed)
547     {
548         LogError("Failed to open widget package");
549         printf("failed: widget package does not exist\n");
550         m_returnStatus = -1;
551         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
552             PostEvent(
553             WRTInstallerNS::QuitEvent());
554     }
555     Catch(DPL::ZipInput::Exception::OpenFileFailed)
556     {
557         printf("failed: widget config file does not exist\n");
558         LogError("Failed to open config.xml file");
559         m_returnStatus = -1;
560         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
561             PostEvent(
562             WRTInstallerNS::QuitEvent());
563     }
564     Catch(ElementParser::Exception::ParseError)
565     {
566         printf("failed: can not parse config file\n");
567         LogError("Failed to parse config.xml file");
568         m_returnStatus = -1;
569         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
570             PostEvent(
571             WRTInstallerNS::QuitEvent());
572     }
573 }
574
575 void WrtInstaller::shutdownStep()
576 {
577     LogDebug("Closing Wrt connection ...");
578     if (m_initialized) {
579         wrt_installer_shutdown();
580         m_initialized = false;
581         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
582             PostEvent(
583             WRTInstallerNS::QuitEvent());
584     }
585 }
586
587 void WrtInstaller::staticWrtInitCallback(WrtErrStatus status,
588                                          void* userdata)
589 {
590     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
591     Assert(This);
592
593     if (status == WRT_SUCCESS) {
594         LogDebug("Init succesfull");
595         This->m_initialized = true;
596         This->m_returnStatus = 0;
597
598         if (This->popupsEnabled()) {
599             This->m_popup = new InstallerPopup;
600             This->m_popup->init();
601         }
602
603         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
604             ::PostEvent(WRTInstallerNS::NextStepEvent());
605     } else {
606         LogError("Init unsuccesfull");
607         This->m_returnStatus = -1;
608         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
609             PostEvent(
610             WRTInstallerNS::QuitEvent());
611     }
612 }
613
614 void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
615                                            WrtErrStatus status,
616                                            void* userdata)
617 {
618     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
619     Assert(This);
620
621     Step current = This->GetCurrentStep();
622     DPL::String resultMsg;
623     std::string printMsg;
624
625     if (current == &WrtInstaller::installStep) {
626         resultMsg = DPL::FromUTF8String(PKGMGR_INSTALL_MSG);
627         printMsg = "installation";
628     } else if (current == &WrtInstaller::uninstallPkgNameStep ||
629                current == &WrtInstaller::uninstallGuidStep ||
630                current == &WrtInstaller::unistallWgtFileStep)
631     {
632         resultMsg = DPL::FromUTF8String(PKGMGR_UNINSTALL_MSG);
633         printMsg = "uninstallation";
634     }
635
636     if (WRT_SUCCESS != status) {
637         // Failure
638         LogError("Step failed");
639         This->m_returnStatus = -1;
640
641         if (This->popupsEnabled()) {
642             resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_END_FAILURE);
643             This->m_popup->showPopup(This, resultMsg, failResultCallback);
644         } else {
645             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
646                 ::PostEvent(WRTInstallerNS::QuitEvent());
647         }
648
649         switch (status) {
650             case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
651                 This->m_returnStatus = 1; //this status is specific
652                 fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
653                         tizenId.c_str(), printMsg.c_str());
654                 break;
655
656             case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
657                 This->m_returnStatus = 1; //this status is specific
658                 fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
659                         tizenId.c_str(), printMsg.c_str());
660                 break;
661
662             case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
663                 This->m_returnStatus = 1; //this status is specific
664                 fprintf(stderr, "## wrt-installer : %s %s has failed - given"
665                         " version is lower than existing version\n",
666                         tizenId.c_str(), printMsg.c_str());
667                 break;
668
669             case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
670                 This->m_returnStatus = 1; //this status is specific
671                 fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
672                         " file doesn't find in package.\n",
673                         tizenId.c_str(), printMsg.c_str());
674                 break;
675
676             case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
677                 This->m_returnStatus = 1; //this status is specific
678                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
679                         "invalid manifestx.xml\n",
680                         tizenId.c_str(), printMsg.c_str());
681                 break;
682
683             case WRT_INSTALLER_CONFIG_NOT_FOUND:
684                 This->m_returnStatus = 1; //this status is specific
685                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
686                         "config.xml does not exist\n",
687                         tizenId.c_str(), printMsg.c_str());
688                 break;
689
690             case WRT_INSTALLER_ERROR_CONFIG_INVALID:
691                 This->m_returnStatus = 1; //this status is specific
692                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
693                         "invalid config.xml\n",
694                         tizenId.c_str(), printMsg.c_str());
695                 break;
696
697             case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
698                 This->m_returnStatus = 1; //this status is specific
699                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
700                         "signature doesn't exist in package.\n",
701                         tizenId.c_str(), printMsg.c_str());
702                 break;
703
704             case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
705                 This->m_returnStatus = 1; //this status is specific
706                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
707                         "invalid signature.\n",
708                         tizenId.c_str(), printMsg.c_str());
709                 break;
710
711             case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
712                 This->m_returnStatus = 1; //this status is specific
713                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
714                         "signature verification failed.\n",
715                         tizenId.c_str(), printMsg.c_str());
716                 break;
717
718             case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
719                 This->m_returnStatus = 1; //this status is specific
720                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
721                         "root certificate could not find.\n",
722                         tizenId.c_str(), printMsg.c_str());
723                 break;
724
725             case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
726                 This->m_returnStatus = 1; //this status is specific
727                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
728                         "invalid certification.\n",
729                         tizenId.c_str(), printMsg.c_str());
730                 break;
731
732             case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
733                 This->m_returnStatus = 1; //this status is specific
734                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
735                         "certificate chain verification failed.\n",
736                         tizenId.c_str(), printMsg.c_str());
737                 break;
738
739             case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
740                 This->m_returnStatus = 1; //this status is specific
741                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
742                         "certificate expired.\n",
743                         tizenId.c_str(), printMsg.c_str());
744                 break;
745
746             case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
747                 This->m_returnStatus = 1; //this status is specific
748                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
749                         "invalid privilege\n",
750                         tizenId.c_str(), printMsg.c_str());
751                 break;
752
753             case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
754                 This->m_returnStatus = 1; //this status is specific
755                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
756                         "menu icon could not find\n",
757                         tizenId.c_str(), printMsg.c_str());
758                 break;
759
760             case WRT_INSTALLER_ERROR_FATAL_ERROR:
761                 This->m_returnStatus = 1; //this status is specific
762                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
763                         "fatal error\n",
764                         tizenId.c_str(), printMsg.c_str());
765                 break;
766
767             case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
768                 This->m_returnStatus = 1; //this status is specific
769                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
770                         "out of storage\n",
771                         tizenId.c_str(), printMsg.c_str());
772                 break;
773
774             case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
775                 This->m_returnStatus = 1; //this status is specific
776                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
777                         "out of memory\n",
778                         tizenId.c_str(), printMsg.c_str());
779                 break;
780
781             case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
782                 This->m_returnStatus = 1; //this status is specific
783                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
784                         "package already installed\n",
785                         tizenId.c_str(), printMsg.c_str());
786                 break;
787
788             case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
789                 This->m_returnStatus = 1; //this status is specific
790                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
791                         "ace check failure\n",
792                         tizenId.c_str(), printMsg.c_str());
793                 break;
794
795             case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
796                 This->m_returnStatus = 1; //this status is specific
797                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
798                         "to create manifest failed\n",
799                         tizenId.c_str(), printMsg.c_str());
800                 break;
801
802             case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
803                 This->m_returnStatus = 1; //this status is specific
804                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
805                         "encryption of resource failed\n",
806                         tizenId.c_str(), printMsg.c_str());
807                 break;
808
809             case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
810                 This->m_returnStatus = 1; //this status is specific
811                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
812                         "installation of osp service failed\n",
813                         tizenId.c_str(), printMsg.c_str());
814                 break;
815
816             case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
817                 This->m_returnStatus = 1; //this status is specific
818                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
819                         "widget uninstallation failed\n",
820                         tizenId.c_str(), printMsg.c_str());
821                 break;
822
823
824             case WRT_INSTALLER_ERROR_UNKNOWN:
825                 fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
826                         tizenId.c_str(), printMsg.c_str());
827                 break;
828
829             default:
830                 break;
831         }
832     } else {
833         fprintf(stderr,
834                 "## wrt-installer : %s %s was successful.\n",
835                 tizenId.c_str(),
836                 printMsg.c_str());
837         LogDebug("Status succesfull");
838         This->m_returnStatus = 0;
839         resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_END_SUCCESS);
840
841         if (This->popupsEnabled()) {
842             This->m_popup->showPopup(This, resultMsg, showResultCallback);
843         } else {
844             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
845                                                          NextStepEvent>
846                 ::PostEvent(WRTInstallerNS::NextStepEvent());
847         }
848     }
849 }
850
851 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
852                                                        void* userdata)
853 {
854     Assert(userdata);
855
856     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
857
858     WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
859
860     std::string path = std::string(data->pluginPath);
861     delete data;
862
863     This->m_numPluginsToInstall--;
864     LogDebug("Plugins to install: " << This->m_numPluginsToInstall);
865
866     if (This->m_numPluginsToInstall < 1) {
867         LogDebug("All plugins installation completed");
868         fprintf(stderr, "All plugins installation completed.\n");
869
870         //remove installation request
871         if (!PluginUtils::removeInstallationRequiredFlag()) {
872             LogInfo("Failed to remove file initializing plugin installation");
873         }
874
875         //remove lock file
876         if (!PluginUtils::unlockPluginInstallation()) {
877             LogInfo("Failed to remove installation lock");
878         }
879
880         if (This->popupsEnabled()) {
881             This->m_popup->init();
882             elm_progressbar_value_set(This->m_popup->m_progressbar, 100.0);
883             evas_object_show(This->m_popup->m_popup);
884         }
885
886         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
887             ::PostEvent(WRTInstallerNS::NextStepEvent());
888     } else {
889         if (This->popupsEnabled()) {
890             This->m_popup->init();
891             float percent =
892                 (This->m_totalPlugins -
893                  This->m_numPluginsToInstall) / (float)This->m_totalPlugins;
894             elm_progressbar_value_set(This->m_popup->m_progressbar, percent);
895             evas_object_show(This->m_popup->m_popup);
896         }
897
898         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
899                                                      InstallPluginEvent>::
900             PostEvent(
901             WRTInstallerNS::InstallPluginEvent());
902     }
903
904     if (WRT_SUCCESS == status) {
905         This->m_returnStatus = 0;
906         fprintf(stderr,
907                 "## wrt-installer : plugin installation successfull [%s]\n",
908                 path.c_str());
909         LogDebug("One plugin Installation succesfull: " << path);
910         return;
911     }
912
913     // Failure
914     LogWarning("One of the plugins installation failed!: " << path);
915
916     switch (status) {
917     case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
918         LogError("failed: plugin installation failed\n");
919         break;
920
921     case WRT_INSTALLER_ERROR_UNKNOWN:
922         LogError("failed: unknown error\n");
923         break;
924
925     default:
926         break;
927     }
928 }
929
930 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
931                                                     const char* description,
932                                                     void* userdata)
933 {
934     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
935
936     std::string path = std::string(data->pluginPath);
937
938     LogInfo("Plugin Installation: " << path <<
939             " progress: " << percent <<
940             "description " << description);
941 }
942
943 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
944                                                     const char* description,
945                                                     void* userdata)
946 {
947     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
948     LogInfo(" progress: " << percent <<
949             " description: " << description);
950
951     if (This->popupsEnabled()) {
952         This->m_popup->init();
953         elm_progressbar_value_set(This->m_popup->m_progressbar, percent / 100.0);
954         evas_object_show(This->m_popup->m_popup);
955     }
956 }
957 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
958                                                       const char* description,
959                                                       void* userdata)
960 {
961     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
962     LogInfo(" progress: " << percent <<
963             " description: " << description);
964
965     if (This->popupsEnabled()) {
966         This->m_popup->init();
967         elm_progressbar_value_set(This->m_popup->m_progressbar, percent / 100.0);
968         evas_object_show(This->m_popup->m_popup);
969     }
970 }
971
972 WrtInstaller::InstallerPopup::InstallerPopup() :
973     m_win(NULL),
974     m_popup(NULL),
975     m_progressbar(NULL)
976 {}
977
978 WrtInstaller::InstallerPopup::~InstallerPopup()
979 {
980     LogDebug("App Finished");
981 }
982
983 void WrtInstaller::InstallerPopup::init()
984 {
985     LogDebug("Window Init");
986
987     if (m_win == NULL) {
988         // create window
989         m_win = createWin("wrt-installer");
990
991         // create popup
992         m_popup = elm_popup_add(m_win);
993
994         // create progressbar
995         m_progressbar = elm_progressbar_add(m_popup);
996         elm_object_style_set(m_progressbar, "list_progress");
997         elm_progressbar_horizontal_set(m_progressbar, EINA_TRUE);
998         evas_object_size_hint_align_set(m_progressbar, EVAS_HINT_FILL,
999                                         EVAS_HINT_FILL);
1000         evas_object_size_hint_weight_set(m_progressbar, EVAS_HINT_EXPAND,
1001                                          EVAS_HINT_EXPAND);
1002         elm_object_content_set(m_popup, m_progressbar);
1003         elm_progressbar_value_set(m_progressbar, 0.0);
1004         evas_object_show(m_progressbar);
1005
1006         evas_object_show(m_popup);
1007         evas_object_show(m_win);
1008     }
1009 }
1010
1011 Evas_Object* WrtInstaller::InstallerPopup::createWin(const char *name)
1012 {
1013     Evas_Object *win;
1014     win = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC);
1015
1016     int w, h;
1017     if (!win) {
1018         return NULL;
1019     }
1020
1021     elm_win_alpha_set(win, EINA_TRUE);
1022     elm_win_title_set(win, name);
1023     elm_win_borderless_set(win, EINA_TRUE);
1024     elm_win_raise(win);
1025
1026     ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
1027     evas_object_resize(win, w, h);
1028     return win;
1029 }
1030
1031 void WrtInstaller::InstallerPopup::showPopup(void* userdata,
1032                                              const DPL::String& pkgMsg,
1033                                              ShowResultCallback callback)
1034 {
1035     Evas_Object *btn;
1036
1037     LogDebug("Result Popup Created");
1038     evas_object_del(m_popup);
1039     m_popup = NULL;
1040
1041     m_popup = elm_popup_add(m_win);
1042     if (!m_popup) {
1043         return;
1044     }
1045
1046     btn = elm_button_add(m_popup);
1047     if (!btn) {
1048         evas_object_del(m_popup);
1049         return;
1050     }
1051     elm_object_text_set(btn, "OK");
1052     evas_object_smart_callback_add(btn, "clicked", callback, userdata);
1053     elm_object_part_content_set(m_popup, "button1", btn);
1054     elm_object_part_text_set(m_popup, "title,text", "RESULT");
1055     elm_object_text_set(m_popup, DPL::ToUTF8String(pkgMsg).c_str());
1056
1057     evas_object_show(m_popup);
1058     evas_object_show(m_win);
1059 }
1060
1061 void WrtInstaller::showResultCallback(void *data, Evas_Object* /*obj*/,
1062                                       void* /*event_info*/)
1063 {
1064     WrtInstaller *This = static_cast<WrtInstaller*>(data);
1065     Assert(This);
1066
1067     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
1068         ::PostEvent(WRTInstallerNS::NextStepEvent());
1069 }
1070
1071 void WrtInstaller::failResultCallback(void *data, Evas_Object* /*obj*/,
1072                                       void* /*event_info*/)
1073 {
1074     WrtInstaller *This = static_cast<WrtInstaller*>(data);
1075     Assert(This);
1076
1077     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
1078         ::PostEvent(WRTInstallerNS::QuitEvent());
1079 }
1080
1081 void WrtInstaller::installNewPlugins()
1082 {
1083     LogDebug("Install new plugins");
1084
1085     if (!PluginUtils::lockPluginInstallation()) {
1086         LogInfo("Lock NOT created");
1087         return;
1088     }
1089
1090     if (!PluginUtils::checkPluginInstallationRequired()) {
1091         LogDebug("Plugin installation not required");
1092         PluginUtils::unlockPluginInstallation();
1093         return;
1094     }
1095
1096     m_startupPluginInstallation = true;
1097     AddStep(&WrtInstaller::installPluginsStep);
1098 }
1099
1100 bool WrtInstaller::popupsEnabled() const
1101 {
1102     return !m_quiet && !GlobalSettings::PopupsTestModeEnabled();
1103 }
1104
1105 int main(int argc, char *argv[])
1106 {
1107     UNHANDLED_EXCEPTION_HANDLER_BEGIN
1108     {
1109         // Output on stdout will be flushed after every newline character,
1110         // even if it is redirected to a pipe. This is useful for running
1111         // from a script and parsing output.
1112         // (Standard behavior of stdlib is to use full buffering when
1113         // redirected to a pipe, which means even after an end of line
1114         // the output may not be flushed).
1115         setlinebuf(stdout);
1116
1117         // Check and re-set the file open limitation
1118         struct rlimit rlim;
1119         if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
1120             LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")");
1121             LogDebug("RLIMIT_NOFILE hrd(" << rlim.rlim_max << ")");
1122
1123             if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
1124                 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
1125                 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
1126                 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
1127                     LogError("setrlimit is fail!!");
1128                 }
1129             }
1130         } else {
1131             LogError("getrlimit is fail!!");
1132         }
1133
1134         // set evas backend type for emulator
1135         // popup isn't showed in the emulator,
1136         // if backend isn't set to SW backend
1137         if (GlobalSettings::IsEmulator()) {
1138             if (setenv("ELM_ENGINE", "x11", 1)) {
1139                 LogDebug("Enable backend");
1140             }
1141         }
1142
1143         WrtInstaller app(argc, argv);
1144         int ret = app.Exec();
1145         LogDebug("App returned: " << ret);
1146         ret = app.getReturnStatus();
1147         LogDebug("WrtInstaller returned: " << ret);
1148         return ret;
1149     }
1150     UNHANDLED_EXCEPTION_HANDLER_END
1151 }