[Release] wrt-installer_0.1.23
[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 {
293             return showHelpAndQuit();
294         }
295     } else if (arg.find("backend") != std::string::npos) {
296         using namespace PackageManager;
297         m_installByPkgmgr = true;
298
299         auto pkgmgrSignal = std::shared_ptr<PackageManager::PkgmgrSignal>(
300                 new PackageManager::PkgmgrSignal()
301                 );
302
303         pkgmgrSignal->initialize(m_argc, m_argv);
304         m_quiet = pkgmgrSignal->isNoPopupRequired();
305         LogDebug("backend m_quiet" << m_quiet);
306
307         int reqType = pkgmgrSignal->getRequestedType();
308
309         pkgmgrSignalInterface =
310             std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
311                 pkgmgrSignal);
312         switch (reqType) {
313         case PKGMGR_REQ_INSTALL:
314             m_packagePath = m_argv[4];
315             struct stat info;
316             if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
317                 LogInfo("Installing package directly from directory");
318                 m_installMode = WRT_INSTALL_MODE_INSTALL_DIRECTORY;
319             } else {
320                 LogInfo("Installing from regular location");
321                 m_installMode = WRT_INSTALL_MODE_INSTALL_WGT;
322             }
323             AddStep(&WrtInstaller::installStep);
324             break;
325         case PKGMGR_REQ_UNINSTALL:
326             m_name = m_argv[4];
327             AddStep(&WrtInstaller::uninstallPkgNameStep);
328             break;
329         default:
330             LogDebug("Not available type");
331             break;
332         }
333     }
334
335     AddStep(&WrtInstaller::shutdownStep);
336     DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
337         PostEvent(
338         WRTInstallerNS::NextStepEvent());
339 }
340
341 void WrtInstaller::OnReset(bundle* /*b*/)
342 {
343     LogDebug("OnReset");
344 }
345
346 void WrtInstaller::OnTerminate()
347 {
348     LogDebug("Wrt Shutdown now");
349     PluginUtils::unlockPluginInstallation();
350     if (m_initialized) {
351         wrt_installer_shutdown();
352     }
353     delete m_popup;
354 }
355
356 void WrtInstaller::showHelpAndQuit()
357 {
358     printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/PATH]...\n"
359            "Operate with WebRuntime daemon: install, uninstall"
360            " and launch widgets.\n"
361            "Query list of installed widgets and setup up debugging support.\n"
362            "\n"
363            "Exactly one option must be selected.\n"
364            "Mandatory arguments to long options are mandatory for short "
365            "options too.\n"
366            "  -h,    --help                                 show this help\n"
367            "  -p,    --install-plugins                      install plugins\n"
368            "  -i,    --install                              "
369            "install or update widget package for given path\n"
370            "  -un,   --uninstall-name                       "
371            "uninstall widget for given package name\n"
372            "  -up,   --uninstall-packagepath                "
373            "uninstall widget for given package file path\n"
374            "\n");
375
376     Quit();
377 }
378
379 void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
380 {
381     LogDebug("Quiting");
382
383     if (m_initialized) {
384         LogDebug("Wrt Shutdown now");
385         SwitchToStep(&WrtInstaller::shutdownStep);
386         DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
387             PostEvent(
388             WRTInstallerNS::NextStepEvent());
389     } else {
390         LogDebug("Quiting application");
391         return Quit();
392     }
393 }
394
395 void WrtInstaller::OnEventReceived(
396     const WRTInstallerNS::NextStepEvent& /*event*/)
397 {
398     LogDebug("Executing next step");
399     NextStep();
400 }
401
402 void WrtInstaller::OnEventReceived(
403     const WRTInstallerNS::InstallPluginEvent& /*event*/)
404 {
405     PluginInstallerData* privateData = new PluginInstallerData;
406     privateData->wrtInstaller = this;
407
408     if (!(*m_pluginsPaths).empty()) {
409         privateData->pluginPath = (*m_pluginsPaths).front();
410         (*m_pluginsPaths).pop_front();
411
412         wrt_install_plugin(privateData->pluginPath.c_str(),
413                            static_cast<void*>(privateData),
414                            &staticWrtPluginInstallationCallback,
415                            &staticWrtPluginInstallProgressCb);
416     } else {
417         delete privateData;
418     }
419 }
420
421 void WrtInstaller::initStep()
422 {
423     wrt_installer_init(this, staticWrtInitCallback);
424 }
425
426 void WrtInstaller::installStep()
427 {
428     LogDebug("Installing widget ...");
429     std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
430                                                         m_packagePath.c_str()));
431
432     wrt_install_widget(packagePath ? packagePath.get() : m_packagePath.c_str(),
433                        this, &staticWrtStatusCallback,
434                        (!m_quiet || m_installByPkgmgr)
435                        ? &staticWrtInstallProgressCallback : NULL,
436                        m_installMode,
437                        m_quiet,
438                        pkgmgrSignalInterface);
439 }
440
441 void WrtInstaller::installPluginsStep()
442 {
443     LogDebug("Installing plugins ...");
444     fprintf(stderr, "Installing plugins ...\n");
445
446     if (m_startupPluginInstallation) {
447         LogInfo("Plugin installation started because new plugin package found");
448     } else if (!PluginUtils::lockPluginInstallation()) {
449         LogError("Failed to open plugin installation lock file"
450                  " Plugins are currently installed by other process");
451         staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
452                                             this);
453         return;
454     }
455
456     std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
457
458     DIR *dir;
459     dir = opendir(PLUGIN_PATH.c_str());
460
461     if (!dir) {
462         return;
463     }
464
465     LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
466
467     std::list<std::string> pluginsPaths;
468     struct dirent libdir;
469     struct dirent *result;
470     int return_code;
471     errno = 0;
472     for (return_code = readdir_r(dir, &libdir, &result);
473             result != NULL && return_code == 0;
474             return_code = readdir_r(dir, &libdir, &result))
475     {
476         if (strcmp(libdir.d_name, ".") == 0 ||
477             strcmp(libdir.d_name, "..") == 0)
478         {
479             continue;
480         }
481
482         std::string path = PLUGIN_PATH;
483         path += "/";
484         path += libdir.d_name;
485
486         struct stat tmp;
487
488         if (stat(path.c_str(), &tmp) == -1) {
489             LogError("Failed to open file" << path);
490             continue;
491         }
492
493         if (!S_ISDIR(tmp.st_mode)) {
494             LogError("Not a directory" << path);
495             continue;
496         }
497
498         pluginsPaths.push_back(path);
499     }
500
501     if (return_code != 0 || errno != 0) {
502         LogError("readdir_r() failed with " << DPL::GetErrnoString());
503     }
504
505     //set nb of plugins to install
506     //this value indicate how many callbacks are expected
507     m_numPluginsToInstall = pluginsPaths.size();
508     LogInfo("Plugins to install: " << m_numPluginsToInstall);
509     m_pluginsPaths = pluginsPaths;
510
511     m_totalPlugins = m_numPluginsToInstall;
512     DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
513         ::PostEvent(WRTInstallerNS::InstallPluginEvent());
514
515     if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
516         LogError("Failed to close dir: " << PLUGIN_PATH << " with error: "
517                                          << DPL::GetErrnoString());
518     }
519 }
520
521 void WrtInstaller::uninstallPkgNameStep()
522 {
523     LogDebug("Uninstalling widget ...");
524     LogDebug("Package name : " << m_name);
525     wrt_uninstall_widget(m_name.c_str(), this, &staticWrtStatusCallback,
526                          (!m_quiet || m_installByPkgmgr)
527                          ? &staticWrtUninstallProgressCallback : NULL,
528                          pkgmgrSignalInterface);
529 }
530
531 void WrtInstaller::unistallWgtFileStep()
532 {
533     LogDebug("Uninstalling widget ...");
534
535     Try {
536         // Parse config
537         ParserRunner parser;
538         ConfigParserData configInfo;
539
540         // Open zip file
541         std::unique_ptr<DPL::ZipInput> zipFile(
542             new DPL::ZipInput(m_packagePath));
543         std::unique_ptr<DPL::ZipInput::File> configFile;
544
545         Try {
546             // Open config.xml file
547             configFile.reset(zipFile->OpenFile(CONFIG_XML));
548         }
549         Catch(DPL::ZipInput::Exception::OpenFileFailed)
550         {
551             // Open config.xml file for hybrid
552             configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
553         }
554
555         // Extract config
556         DPL::BinaryQueue buffer;
557         DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
558         DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
559         DPL::Copy(&inputAdapter, &outputAdapter);
560         parser.Parse(&buffer,
561                      ElementParserPtr(
562                          new RootParser<WidgetParser>(configInfo,
563                                                       DPL::FromUTF32String(
564                                                           L"widget"))));
565
566         DPL::OptionalString pkgId = configInfo.tizenPkgId;
567         if (!pkgId.IsNull()) {
568             LogDebug("Pkgid from packagePath : " << pkgId);
569             wrt_uninstall_widget(
570                 DPL::ToUTF8String(*pkgId).c_str(), this, &staticWrtStatusCallback,
571                 !m_quiet ? &staticWrtUninstallProgressCallback
572                 : NULL,
573                 pkgmgrSignalInterface);
574         } else {
575             LogError("Fail to uninstalling widget... ");
576             m_returnStatus = -1;
577             DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
578                 PostEvent(
579                 WRTInstallerNS::QuitEvent());
580         }
581     }
582     Catch(DPL::ZipInput::Exception::OpenFailed)
583     {
584         LogError("Failed to open widget package");
585         printf("failed: widget package does not exist\n");
586         m_returnStatus = -1;
587         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
588             PostEvent(
589             WRTInstallerNS::QuitEvent());
590     }
591     Catch(DPL::ZipInput::Exception::OpenFileFailed)
592     {
593         printf("failed: widget config file does not exist\n");
594         LogError("Failed to open config.xml file");
595         m_returnStatus = -1;
596         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
597             PostEvent(
598             WRTInstallerNS::QuitEvent());
599     }
600     Catch(ElementParser::Exception::ParseError)
601     {
602         printf("failed: can not parse config file\n");
603         LogError("Failed to parse config.xml file");
604         m_returnStatus = -1;
605         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
606             PostEvent(
607             WRTInstallerNS::QuitEvent());
608     }
609 }
610
611 void WrtInstaller::shutdownStep()
612 {
613     LogDebug("Closing Wrt connection ...");
614     if (m_initialized) {
615         wrt_installer_shutdown();
616         m_initialized = false;
617         DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
618             PostEvent(
619             WRTInstallerNS::QuitEvent());
620     }
621 }
622
623 void WrtInstaller::staticWrtInitCallback(WrtErrStatus status,
624                                          void* userdata)
625 {
626     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
627     Assert(This);
628
629     if (status == WRT_SUCCESS) {
630         LogDebug("Init succesfull");
631         This->m_initialized = true;
632         This->m_returnStatus = 0;
633
634         if (This->popupsEnabled()) {
635             This->m_popup = new InstallerPopup;
636             This->m_popup->init();
637         }
638
639         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
640             ::PostEvent(WRTInstallerNS::NextStepEvent());
641     } else {
642         LogError("Init unsuccesfull");
643         This->m_returnStatus = -1;
644         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
645             PostEvent(
646             WRTInstallerNS::QuitEvent());
647     }
648 }
649
650 void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
651                                            WrtErrStatus status,
652                                            void* userdata)
653 {
654     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
655     Assert(This);
656
657     Step current = This->GetCurrentStep();
658     DPL::String resultMsg;
659     std::string printMsg;
660
661     if (current == &WrtInstaller::installStep) {
662         resultMsg = DPL::FromUTF8String(PKGMGR_INSTALL_MSG);
663         printMsg = "installation";
664     } else if (current == &WrtInstaller::uninstallPkgNameStep ||
665                current == &WrtInstaller::unistallWgtFileStep)
666     {
667         resultMsg = DPL::FromUTF8String(PKGMGR_UNINSTALL_MSG);
668         printMsg = "uninstallation";
669     }
670
671     if (WRT_SUCCESS != status) {
672         // Failure
673         LogError("Step failed");
674         This->m_returnStatus = -1;
675
676         if (This->popupsEnabled()) {
677             resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_END_FAILURE);
678             This->m_popup->showPopup(This, resultMsg, failResultCallback);
679         } else {
680             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
681                 ::PostEvent(WRTInstallerNS::QuitEvent());
682         }
683
684         switch (status) {
685             case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
686                 This->m_returnStatus = 1; //this status is specific
687                 fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
688                         tizenId.c_str(), printMsg.c_str());
689                 break;
690
691             case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
692                 This->m_returnStatus = 1; //this status is specific
693                 fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
694                         tizenId.c_str(), printMsg.c_str());
695                 break;
696
697             case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
698                 This->m_returnStatus = 1; //this status is specific
699                 fprintf(stderr, "## wrt-installer : %s %s has failed - given"
700                         " version is lower than existing version\n",
701                         tizenId.c_str(), printMsg.c_str());
702                 break;
703
704             case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
705                 This->m_returnStatus = 1; //this status is specific
706                 fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
707                         " file doesn't find in package.\n",
708                         tizenId.c_str(), printMsg.c_str());
709                 break;
710
711             case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
712                 This->m_returnStatus = 1; //this status is specific
713                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
714                         "invalid manifestx.xml\n",
715                         tizenId.c_str(), printMsg.c_str());
716                 break;
717
718             case WRT_INSTALLER_CONFIG_NOT_FOUND:
719                 This->m_returnStatus = 1; //this status is specific
720                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
721                         "config.xml does not exist\n",
722                         tizenId.c_str(), printMsg.c_str());
723                 break;
724
725             case WRT_INSTALLER_ERROR_CONFIG_INVALID:
726                 This->m_returnStatus = 1; //this status is specific
727                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
728                         "invalid config.xml\n",
729                         tizenId.c_str(), printMsg.c_str());
730                 break;
731
732             case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
733                 This->m_returnStatus = 1; //this status is specific
734                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
735                         "signature doesn't exist in package.\n",
736                         tizenId.c_str(), printMsg.c_str());
737                 break;
738
739             case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
740                 This->m_returnStatus = 1; //this status is specific
741                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
742                         "invalid signature.\n",
743                         tizenId.c_str(), printMsg.c_str());
744                 break;
745
746             case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
747                 This->m_returnStatus = 1; //this status is specific
748                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
749                         "signature verification failed.\n",
750                         tizenId.c_str(), printMsg.c_str());
751                 break;
752
753             case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
754                 This->m_returnStatus = 1; //this status is specific
755                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
756                         "root certificate could not find.\n",
757                         tizenId.c_str(), printMsg.c_str());
758                 break;
759
760             case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
761                 This->m_returnStatus = 1; //this status is specific
762                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
763                         "invalid certification.\n",
764                         tizenId.c_str(), printMsg.c_str());
765                 break;
766
767             case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
768                 This->m_returnStatus = 1; //this status is specific
769                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
770                         "certificate chain verification failed.\n",
771                         tizenId.c_str(), printMsg.c_str());
772                 break;
773
774             case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
775                 This->m_returnStatus = 1; //this status is specific
776                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
777                         "certificate expired.\n",
778                         tizenId.c_str(), printMsg.c_str());
779                 break;
780
781             case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
782                 This->m_returnStatus = 1; //this status is specific
783                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
784                         "invalid privilege\n",
785                         tizenId.c_str(), printMsg.c_str());
786                 break;
787
788             case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
789                 This->m_returnStatus = 1; //this status is specific
790                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
791                         "menu icon could not find\n",
792                         tizenId.c_str(), printMsg.c_str());
793                 break;
794
795             case WRT_INSTALLER_ERROR_FATAL_ERROR:
796                 This->m_returnStatus = 1; //this status is specific
797                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
798                         "fatal error\n",
799                         tizenId.c_str(), printMsg.c_str());
800                 break;
801
802             case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
803                 This->m_returnStatus = 1; //this status is specific
804                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
805                         "out of storage\n",
806                         tizenId.c_str(), printMsg.c_str());
807                 break;
808
809             case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
810                 This->m_returnStatus = 1; //this status is specific
811                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
812                         "out of memory\n",
813                         tizenId.c_str(), printMsg.c_str());
814                 break;
815
816             case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
817                 This->m_returnStatus = 1; //this status is specific
818                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
819                         "package already installed\n",
820                         tizenId.c_str(), printMsg.c_str());
821                 break;
822
823             case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
824                 This->m_returnStatus = 1; //this status is specific
825                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
826                         "ace check failure\n",
827                         tizenId.c_str(), printMsg.c_str());
828                 break;
829
830             case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
831                 This->m_returnStatus = 1; //this status is specific
832                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
833                         "to create manifest failed\n",
834                         tizenId.c_str(), printMsg.c_str());
835                 break;
836
837             case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
838                 This->m_returnStatus = 1; //this status is specific
839                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
840                         "encryption of resource failed\n",
841                         tizenId.c_str(), printMsg.c_str());
842                 break;
843
844             case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
845                 This->m_returnStatus = 1; //this status is specific
846                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
847                         "installation of osp service failed\n",
848                         tizenId.c_str(), printMsg.c_str());
849                 break;
850
851             case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
852                 This->m_returnStatus = 1; //this status is specific
853                 fprintf(stderr, "## wrt-installer : %s %s has failed - "
854                         "widget uninstallation failed\n",
855                         tizenId.c_str(), printMsg.c_str());
856                 break;
857
858
859             case WRT_INSTALLER_ERROR_UNKNOWN:
860                 fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
861                         tizenId.c_str(), printMsg.c_str());
862                 break;
863
864             default:
865                 break;
866         }
867     } else {
868         fprintf(stderr,
869                 "## wrt-installer : %s %s was successful.\n",
870                 tizenId.c_str(),
871                 printMsg.c_str());
872         LogDebug("Status succesfull");
873         This->m_returnStatus = 0;
874         resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_END_SUCCESS);
875
876         if (This->popupsEnabled()) {
877             This->m_popup->showPopup(This, resultMsg, showResultCallback);
878         } else {
879             This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
880                                                          NextStepEvent>
881                 ::PostEvent(WRTInstallerNS::NextStepEvent());
882         }
883     }
884 }
885
886 void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status,
887                                                        void* userdata)
888 {
889     Assert(userdata);
890
891     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
892
893     WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller);
894
895     std::string path = std::string(data->pluginPath);
896     delete data;
897
898     This->m_numPluginsToInstall--;
899     LogDebug("Plugins to install: " << This->m_numPluginsToInstall);
900
901     if (This->m_numPluginsToInstall < 1) {
902         LogDebug("All plugins installation completed");
903         fprintf(stderr, "All plugins installation completed.\n");
904
905         //remove installation request
906         if (!PluginUtils::removeInstallationRequiredFlag()) {
907             LogInfo("Failed to remove file initializing plugin installation");
908         }
909
910         //remove lock file
911         if (!PluginUtils::unlockPluginInstallation()) {
912             LogInfo("Failed to remove installation lock");
913         }
914
915         if (This->popupsEnabled()) {
916             This->m_popup->init();
917             elm_progressbar_value_set(This->m_popup->m_progressbar, 100.0);
918             evas_object_show(This->m_popup->m_popup);
919         }
920
921         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
922             ::PostEvent(WRTInstallerNS::NextStepEvent());
923     } else {
924         if (This->popupsEnabled()) {
925             This->m_popup->init();
926             float percent =
927                 (This->m_totalPlugins -
928                  This->m_numPluginsToInstall) / (float)This->m_totalPlugins;
929             elm_progressbar_value_set(This->m_popup->m_progressbar, percent);
930             evas_object_show(This->m_popup->m_popup);
931         }
932
933         This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
934                                                      InstallPluginEvent>::
935             PostEvent(
936             WRTInstallerNS::InstallPluginEvent());
937     }
938
939     if (WRT_SUCCESS == status) {
940         This->m_returnStatus = 0;
941         fprintf(stderr,
942                 "## wrt-installer : plugin installation successfull [%s]\n",
943                 path.c_str());
944         LogDebug("One plugin Installation succesfull: " << path);
945         return;
946     }
947
948     // Failure
949     LogWarning("One of the plugins installation failed!: " << path);
950
951     switch (status) {
952     case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
953         LogError("failed: plugin installation failed\n");
954         break;
955
956     case WRT_INSTALLER_ERROR_UNKNOWN:
957         LogError("failed: unknown error\n");
958         break;
959
960     default:
961         break;
962     }
963 }
964
965 void WrtInstaller::staticWrtPluginInstallProgressCb(float percent,
966                                                     const char* description,
967                                                     void* userdata)
968 {
969     PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata);
970
971     std::string path = std::string(data->pluginPath);
972
973     LogInfo("Plugin Installation: " << path <<
974             " progress: " << percent <<
975             "description " << description);
976 }
977
978 void WrtInstaller::staticWrtInstallProgressCallback(float percent,
979                                                     const char* description,
980                                                     void* userdata)
981 {
982     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
983     LogInfo(" progress: " << percent <<
984             " description: " << description);
985
986     if (This->popupsEnabled()) {
987         This->m_popup->init();
988         elm_progressbar_value_set(This->m_popup->m_progressbar, percent / 100.0);
989         evas_object_show(This->m_popup->m_popup);
990     }
991 }
992 void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
993                                                       const char* description,
994                                                       void* userdata)
995 {
996     WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
997     LogInfo(" progress: " << percent <<
998             " description: " << description);
999
1000     if (This->popupsEnabled()) {
1001         This->m_popup->init();
1002         elm_progressbar_value_set(This->m_popup->m_progressbar, percent / 100.0);
1003         evas_object_show(This->m_popup->m_popup);
1004     }
1005 }
1006
1007 void WrtInstaller::showResultCallback(void *data, Evas_Object* /*obj*/,
1008                                       void* /*event_info*/)
1009 {
1010     WrtInstaller *This = static_cast<WrtInstaller*>(data);
1011     Assert(This);
1012
1013     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
1014         ::PostEvent(WRTInstallerNS::NextStepEvent());
1015 }
1016
1017 void WrtInstaller::failResultCallback(void *data, Evas_Object* /*obj*/,
1018                                       void* /*event_info*/)
1019 {
1020     WrtInstaller *This = static_cast<WrtInstaller*>(data);
1021     Assert(This);
1022
1023     This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
1024         ::PostEvent(WRTInstallerNS::QuitEvent());
1025 }
1026
1027 void WrtInstaller::installNewPlugins()
1028 {
1029     LogDebug("Install new plugins");
1030
1031     if (!PluginUtils::lockPluginInstallation()) {
1032         LogInfo("Lock NOT created");
1033         return;
1034     }
1035
1036     if (!PluginUtils::checkPluginInstallationRequired()) {
1037         LogDebug("Plugin installation not required");
1038         PluginUtils::unlockPluginInstallation();
1039         return;
1040     }
1041
1042     m_startupPluginInstallation = true;
1043     AddStep(&WrtInstaller::installPluginsStep);
1044 }
1045
1046 bool WrtInstaller::popupsEnabled() const
1047 {
1048     return !m_quiet && !GlobalSettings::PopupsTestModeEnabled();
1049 }
1050
1051 int main(int argc, char *argv[])
1052 {
1053     UNHANDLED_EXCEPTION_HANDLER_BEGIN
1054     {
1055         // Output on stdout will be flushed after every newline character,
1056         // even if it is redirected to a pipe. This is useful for running
1057         // from a script and parsing output.
1058         // (Standard behavior of stdlib is to use full buffering when
1059         // redirected to a pipe, which means even after an end of line
1060         // the output may not be flushed).
1061         setlinebuf(stdout);
1062
1063         // Check and re-set the file open limitation
1064         struct rlimit rlim;
1065         if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
1066             LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")");
1067             LogDebug("RLIMIT_NOFILE hrd(" << rlim.rlim_max << ")");
1068
1069             if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
1070                 rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
1071                 rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
1072                 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
1073                     LogError("setrlimit is fail!!");
1074                 }
1075             }
1076         } else {
1077             LogError("getrlimit is fail!!");
1078         }
1079
1080         // set evas backend type for emulator
1081         // popup isn't showed in the emulator,
1082         // if backend isn't set to SW backend
1083         if (GlobalSettings::IsEmulator()) {
1084             if (setenv("ELM_ENGINE", "x11", 1)) {
1085                 LogDebug("Enable backend");
1086             }
1087         }
1088
1089         WrtInstaller app(argc, argv);
1090         int ret = app.Exec();
1091         LogDebug("App returned: " << ret);
1092         ret = app.getReturnStatus();
1093         LogDebug("WrtInstaller returned: " << ret);
1094         return ret;
1095     }
1096     UNHANDLED_EXCEPTION_HANDLER_END
1097 }