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