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