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