Removal of factory_widget attribute and related functions.
[platform/framework/web/wrt-plugins-common.git] / src / plugins-installer / wrt-installer / wrt_installer_api.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 /**
17  * @file        wrt_installer_api.cpp
18  * @author      Chung Jihoon (jihoon.chung@samsung.com)
19  * @version     1.0
20  * @brief       This file contains definitions of wrt installer api
21  */
22 #include <stdlib.h>
23 #include <list>
24 #include <string>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <dpl/exception.h>
29 #include <dpl/log/log.h>
30 #include <dpl/assert.h>
31 #include <dpl/semaphore.h>
32 #include <dpl/sstream.h>
33 #include <libxml/parser.h>
34 #include <vconf.h>
35
36 #include <wrt_installer_api.h>
37 #include <installer_callbacks_translate.h>
38 #include <installer_controller.h>
39 #include <language_subtag_rst_tree.h>
40 #include <dpl/localization/localization_utils.h>
41 #include <dpl/wrt-dao-ro/global_config.h>
42 #include <dpl/utils/widget_version.h>
43 #include <dpl/popup/popup_manager.h>
44 #include <dpl/popup/popup_controller.h>
45 #include <wrt_type.h>
46 #include <dpl/localization/w3c_file_localization.h>
47 #include <dpl/wrt-dao-ro/WrtDatabase.h>
48 #include <vcore/VCore.h>
49 #include <installer_main_thread.h>
50
51 using namespace WrtDB;
52
53 #undef TRUE
54 #undef FALSE
55 #define TRUE 0
56 #define FALSE -1
57
58 #ifdef __cplusplus
59
60 #define EXPORT_API __attribute__((visibility("default")))
61 extern "C"
62 {
63 #endif
64 //    inline WidgetUpdateMode::Type translateWidgetUpdateMode(
65 //            wrt_widget_update_mode_t updateMode)
66 //    {
67 //        WidgetUpdateMode::Type result = WidgetUpdateMode::Zero;
68 //
69 //        if (updateMode & WRT_WIM_NOT_INSTALLED) {
70 //            result = result | WidgetUpdateMode::NotInstalled;
71 //        }
72 //
73 //        if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) {
74 //            result = result | WidgetUpdateMode::IncomingVersionNotStd;
75 //        }
76 //
77 //        if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) {
78 //            result = result | WidgetUpdateMode::ExistingVersionNotStd;
79 //        }
80 //
81 //        if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) {
82 //            result = result | WidgetUpdateMode::BothVersionsNotStd;
83 //        }
84 //
85 //        if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) {
86 //            result = result | WidgetUpdateMode::ExistingVersionOlder;
87 //        }
88 //
89 //        if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) {
90 //            result = result | WidgetUpdateMode::ExistingVersionEqual;
91 //        }
92 //
93 //        if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) {
94 //            result = result | WidgetUpdateMode::ExistingVersionNewer;
95 //        }
96 //
97 //        return result;
98 //    }
99 //
100 //    void localizationSetting()
101 //    {
102 //        char* lang = vconf_get_str(VCONFKEY_LANGSET);
103 //        if (!lang) {
104 //            LogError("Cannot get locale settings from vconf");
105 //        } else {
106 //            LogDebug("Language set to: " << lang);
107 //
108 //            using namespace LocalizationUtils;
109 //
110 //            LanguageTagsList list;
111 //            list.push_back(DPL::FromUTF8String(lang));
112 //            SetSystemLanguageTags(list);
113 //
114 //            LogDebug("LanguageChanged to " << lang);
115 //        }
116 //    }
117
118     const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock";
119     static int wrt_count_plugin;
120
121     static std::string cutOffFileName(const std::string& path)
122     {
123         size_t found = path.find_last_of("/");
124         if (found == std::string::npos) {
125             return path;
126         } else {
127             return path.substr(0, found);
128         }
129     }
130
131     static bool checkPath(const std::string& path)
132     {
133         struct stat st;
134         if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
135             return true;
136         }
137         LogError("Cannot access directory [ " << path << " ]");
138         return false;
139     }
140
141     static bool checkPaths()
142     {
143         bool if_ok = true;
144         if_ok &= (checkPath(cutOffFileName(
145                 GlobalConfig::GetWrtDatabaseFilePath())));
146         if (!if_ok) {
147             LogError(
148                 "Path <" << GlobalConfig::GetWrtDatabaseFilePath() <<
149                 "> does not exist.");
150         }
151
152         if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
153         if (!if_ok) {
154             LogError(
155                 "Path <" << GlobalConfig::GetDevicePluginPath() <<
156                 "> does not exist.");
157         }
158
159         if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
160         if (!if_ok) {
161             LogError(
162                 "Path <" << GlobalConfig::GetUserInstalledWidgetPath() <<
163                 "> does not exist.");
164         }
165         return if_ok;
166     }
167
168     void plugin_install_status_cb(WrtErrStatus status,
169                                   void* userparam)
170     {
171         Assert(userparam);
172
173         wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam);
174
175         if (--wrt_count_plugin < 1) {
176             LogDebug("All plugins installation completed");
177
178             LogDebug("Call SetAllinstallpluginsCallback");
179             plugin_data->plugin_installed_cb(plugin_data->user_data);
180         }
181
182         if (status == WRT_SUCCESS) {
183             LogInfo(
184                 "plugin installation is successful: " <<
185                 plugin_data->plugin_path);
186             return;
187         }
188
189         LogError("Fail to install plugin : " << plugin_data->plugin_path);
190
191         switch (status) {
192         case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH:
193             LogError("Failed : Plugin install path is wrong");
194             break;
195         case WRT_PLUGIN_INSTALLER_ERROR_METAFILE:
196             LogError("Failed : Plugin Metafile Error");
197             break;
198         case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED:
199             LogError("Failed : This Plugin is already installed");
200             break;
201         case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR:
202             LogError("Failed : Library Error. Missing symbol or structures");
203             break;
204         case WRT_PLUGIN_INSTALLER_ERROR_WAITING:
205             LogError("Failed : Waiting for plugin dependencies");
206             break;
207         case WRT_PLUGIN_INSTALLER_ERROR_LOCK:
208             LogError("Failed : Lock Error");
209             break;
210         case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN:
211             LogError("Failed : Unkown Error");
212             break;
213         default:
214             break;
215         }
216     }
217
218     void plugin_install_progress_cb(float percent,
219                                     const char* description,
220                                     void* userdata)
221     {
222         char *plugin_path = static_cast<char*>(userdata);
223
224         LogInfo("Install plugin : " << plugin_path <<
225                 ", Progress : " << percent <<
226                 ", Description : " << description);
227     }
228
229     EXPORT_API int wrt_installer_init(void *userdata,
230                             WrtInstallerInitCallback callback)
231     {
232         // Set DPL/LOG MID
233         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
234
235         try
236         {
237             LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
238             LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
239
240             // Touch InstallerController Singleton
241             InstallerMainThreadSingleton::Instance().TouchArchitecture();
242
243             // Check paths
244             if (!checkPaths()) {
245                 if (callback) {
246                     callback(WRT_ERROR_NO_PATH, userdata);
247                 }
248                 return TRUE;
249             }
250
251             // Initialize ValidationCore - this must be done before AttachDatabases
252             ValidationCore::VCoreInit(
253                     std::string(GlobalConfig::GetFingerprintListFile()),
254                     std::string(GlobalConfig::GetFingerprintListSchema()),
255                     std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
256
257             InstallerMainThreadSingleton::Instance().AttachDatabases();
258
259             //checking for correct DB version
260 //            if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) {
261 //                LogError("WRONG VERSION OF WRT DATABASE");
262 //                Assert(false && "WRONG VERSION OF WRT DATABASE");
263 //                return FALSE;
264 //            }
265             LogWarning("Database check not implemented!");
266
267             LogInfo("Prepare libxml2 to work in multithreaded program.");
268             xmlInitParser();
269
270             // Initialize Language Subtag registry
271             LanguageSubtagRstTreeSingleton::Instance().Initialize();
272 //            localizationSetting();
273
274             // Installer init
275             CONTROLLER_POST_SYNC_EVENT(
276                     Logic::InstallerController,
277                     InstallerControllerEvents::
278                     InitializeEvent());
279
280             // Install deferred widget packages
281 //            CONTROLLER_POST_EVENT(
282 //                    Logic::InstallerController,
283 //                    InstallerControllerEvents::
284 //                    InstallDeferredWidgetPackagesEvent());
285
286             if (callback) {
287                 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
288                 callback(WRT_SUCCESS, userdata);
289             }
290         }
291         catch (const DPL::Exception& ex)
292         {
293             LogError("Internal Error during Init:");
294             DPL::Exception::DisplayKnownException(ex);
295             if (callback) {
296                 callback(WRT_ERROR_INTERNAL, userdata);
297             }
298             return FALSE;
299         }
300         // OK
301         return TRUE;
302     }
303
304     EXPORT_API void wrt_installer_shutdown()
305     {
306         try
307         {
308             LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
309
310             // Installer termination
311             CONTROLLER_POST_SYNC_EVENT(
312                     Logic::InstallerController,
313                     InstallerControllerEvents::
314                     TerminateEvent());
315
316             InstallerMainThreadSingleton::Instance().DetachDatabases();
317
318             // This must be done after DetachDatabase
319             ValidationCore::VCoreDeinit();
320
321             // Global deinit check
322             LogInfo("Cleanup libxml2 global values.");
323             xmlCleanupParser();
324
325         }
326         catch (const DPL::Exception& ex)
327         {
328             LogError("Internal Error during Shutdown:");
329             DPL::Exception::DisplayKnownException(ex);
330         }
331     }
332
333 //    EXPORT_API void wrt_install_widget(const char *path,
334 //                                       void* userdata,
335 //                                       WrtInstallerStatusCallback status_cb,
336 //                                       WrtProgressCallback progress_cb,
337 //                                       wrt_widget_update_mode_t update_mode,
338 //                                       bool quiet)
339 //    {
340 //        UNHANDLED_EXCEPTION_HANDLER_BEGIN
341 //        {
342 //            LogInfo("[WRT-API] INSTALL WIDGET: " << path);
343 //            // Post installation event
344 //            CONTROLLER_POST_EVENT(
345 //                Logic::InstallerController,
346 //                InstallerControllerEvents::InstallWidgetEvent(
347 //                    path, WidgetInstallationStruct(
348 //                        InstallerCallbacksTranslate::installFinishedCallback,
349 //                        InstallerCallbacksTranslate::installProgressCallback,
350 //                        new InstallerCallbacksTranslate::StatusCallbackStruct(
351 //                            userdata, status_cb, progress_cb),
352 //                        translateWidgetUpdateMode(update_mode),
353 //                        quiet)));
354 //        }
355 //        UNHANDLED_EXCEPTION_HANDLER_END
356 //    }
357 //
358 //    EXPORT_API void wrt_uninstall_widget(int widget_handle,
359 //                                         void* userdata,
360 //                                         WrtInstallerStatusCallback status_cb,
361 //                                         WrtProgressCallback progress_cb)
362 //    {
363 //        UNHANDLED_EXCEPTION_HANDLER_BEGIN
364 //        {
365 //            LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle);
366 //            // Post uninstallation event
367 //            CONTROLLER_POST_EVENT(
368 //                Logic::InstallerController,
369 //                InstallerControllerEvents::UninstallWidgetEvent(
370 //                    widget_handle,
371 //                    WidgetUninstallationStruct(
372 //                        InstallerCallbacksTranslate::uninstallFinishedCallback,
373 //                        InstallerCallbacksTranslate::installProgressCallback,
374 //                        new InstallerCallbacksTranslate::StatusCallbackStruct(
375 //                            userdata, status_cb, progress_cb))));
376 //        }
377 //        UNHANDLED_EXCEPTION_HANDLER_END
378 //    }
379
380     EXPORT_API void wrt_install_plugin(
381         const char *pluginDir,
382         void *user_param,
383         WrtPluginInstallerStatusCallback status_cb,
384         WrtProgressCallback progress_cb)
385     {
386         UNHANDLED_EXCEPTION_HANDLER_BEGIN
387         {
388             LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir);
389             //Private data for status callback
390             //Resource is free in pluginInstallFinishedCallback
391             InstallerCallbacksTranslate::PluginStatusCallbackStruct*
392             callbackStruct =
393                 new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
394                     user_param, status_cb, progress_cb);
395
396             CONTROLLER_POST_EVENT(
397                 Logic::InstallerController,
398                 InstallerControllerEvents::InstallPluginEvent(
399                     std::string(pluginDir),
400                     PluginInstallerStruct(
401                         InstallerCallbacksTranslate::
402                         pluginInstallFinishedCallback,
403                         InstallerCallbacksTranslate::
404                         installProgressCallback, callbackStruct)));
405         }
406         UNHANDLED_EXCEPTION_HANDLER_END
407     }
408
409     EXPORT_API void wrt_install_all_plugins(
410         WrtAllPluginInstalledCallback installed_cb,
411         void *user_param)
412     {
413         UNHANDLED_EXCEPTION_HANDLER_BEGIN
414         {
415             std::string installRequest =
416                 std::string(GlobalConfig::GetPluginInstallInitializerName());
417
418             LogDebug("Install new plugins");
419
420             Try {
421                 DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE);
422             }
423             Catch(DPL::Semaphore::Exception::Base){
424                 LogError("Failed to create installation lock");
425                 return;
426             }
427
428             struct stat tmp;
429
430             if (-1 == stat(installRequest.c_str(), &tmp) ||
431                     !S_ISREG(tmp.st_mode))
432             {
433                 if (ENOENT == errno) {
434                     LogDebug("Plugin installation not required");
435
436                     LogDebug("Call SetAllinstallPluginCallback");
437                     installed_cb(user_param);
438
439                     DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
440                     return;
441                 }
442                 LogWarning("Opening installation request file failed");
443             }
444
445             std::string PLUGIN_PATH =
446                 std::string(GlobalConfig::GetDevicePluginPath());
447
448             DIR *dir;
449             dir = opendir(PLUGIN_PATH.c_str());
450             if (!dir) {
451                 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
452                 return;
453             }
454
455             LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH);
456             struct dirent* libdir;
457
458             errno = 0;
459
460             std::list<std::string> pluginsPaths;
461
462             while ((libdir = readdir(dir)) != 0) {
463                 if (strcmp(libdir->d_name, ".") == 0 ||
464                     strcmp(libdir->d_name, "..") == 0)
465                 {
466                     continue;
467                 }
468
469                 std::string path = PLUGIN_PATH;
470                 path += "/";
471                 path += libdir->d_name;
472
473                 struct stat tmp;
474
475                 if (stat(path.c_str(), &tmp) == -1) {
476                     LogError("Failed to open file" << path);
477                     continue;
478                 }
479
480                 if (!S_ISDIR(tmp.st_mode)) {
481                     LogError("Not a directory" << path);
482                     continue;
483                 }
484
485                 pluginsPaths.push_back(path);
486             }
487
488             wrt_count_plugin = pluginsPaths.size();
489
490             FOREACH(it, pluginsPaths) {
491                 wrt_plugin_data *plugin_data = new wrt_plugin_data;
492
493                 plugin_data->plugin_installed_cb = installed_cb;
494                 plugin_data->plugin_path = const_cast<char*>(it->c_str());
495                 plugin_data->user_data = user_param;
496
497                 wrt_install_plugin(
498                     it->c_str(), static_cast<void*>(plugin_data),
499                     plugin_install_status_cb,
500                     plugin_install_progress_cb);
501             }
502
503             if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
504                 LogError("Failed to close dir: " << PLUGIN_PATH);
505             }
506
507             if (0 != unlink(installRequest.c_str())) {
508                 LogError("Failed to remove file initializing plugin "
509                          "installation");
510             }
511
512             Try {
513                 DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE);
514             }
515             Catch(DPL::Semaphore::Exception::Base){
516                 LogInfo("Failed to remove installation lock");
517             }
518         }
519         UNHANDLED_EXCEPTION_HANDLER_END
520     }
521
522     EXPORT_API int wrt_installer_init_for_tests(void *userdata,
523                             WrtInstallerInitCallback callback)
524     {
525         // Set DPL/LOG MID
526         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
527
528         try
529         {
530             LogInfo("[WRT-API] INITIALIZING WRT INSTALLER...");
531             LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__);
532
533             // Touch InstallerController Singleton
534             InstallerMainThreadSingleton::Instance().
535                 TouchArchitectureOnlyInstaller();
536
537             // Check paths
538             if (!checkPaths()) {
539                 if (callback) {
540                     callback(WRT_ERROR_NO_PATH, userdata);
541                 }
542                 return TRUE;
543             }
544
545             CONTROLLER_POST_SYNC_EVENT(
546                     Logic::InstallerController,
547                     InstallerControllerEvents::
548                     InitializeEvent());
549
550             if (callback) {
551                 LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
552                 callback(WRT_SUCCESS, userdata);
553             }
554         }
555         catch (const DPL::Exception& ex)
556         {
557             LogError("Internal Error during Init:");
558             DPL::Exception::DisplayKnownException(ex);
559             if (callback) {
560                 callback(WRT_ERROR_INTERNAL, userdata);
561             }
562             return FALSE;
563         }
564
565         // OK
566         return TRUE;
567     }
568
569     EXPORT_API void wrt_installer_shutdown_for_tests()
570     {
571         try
572         {
573             LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER...");
574
575             // Installer termination
576             CONTROLLER_POST_SYNC_EVENT(
577                     Logic::InstallerController,
578                     InstallerControllerEvents::
579                     TerminateEvent());
580
581             // Global deinit check
582             LogInfo("Cleanup libxml2 global values.");
583             xmlCleanupParser();
584         }
585         catch (const DPL::Exception& ex)
586         {
587             LogError("Internal Error during Shutdown:");
588             DPL::Exception::DisplayKnownException(ex);
589         }
590     }
591
592     EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname,
593             int *widget_handle)
594     {
595         try
596         {
597             LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : "
598                     << pkgname);
599
600             WidgetHandle handle = WidgetDAOReadOnly::getHandle(
601                     DPL::FromASCIIString(pkgname));
602             *widget_handle = static_cast<int>(handle);
603             return WRT_SUCCESS;
604         }
605         catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
606         {
607             LogError("Error package name is not found");
608             return WRT_ERROR_PKGNAME_NOT_FOUND;
609         }
610         catch (const DPL::Exception& ex)
611         {
612             LogError("Internal Error during get widget id by package name");
613             DPL::Exception::DisplayKnownException(ex);
614             return WRT_ERROR_INTERNAL;
615         }
616     }
617
618     EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid,
619             int *widget_handle)
620     {
621         try
622         {
623             LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : "
624                     << guid);
625
626             WidgetGUID widget_guid = DPL::FromUTF8String(guid);
627             WidgetHandle handle = WidgetDAOReadOnly::getHandle(widget_guid);
628             *widget_handle = static_cast<int>(handle);
629             return WRT_SUCCESS;
630         }
631         catch (WidgetDAOReadOnly::Exception::WidgetNotExist)
632         {
633             LogError("Error package name is not found");
634             return WRT_ERROR_PKGNAME_NOT_FOUND;
635         }
636         catch (const DPL::Exception& ex)
637         {
638             LogError("Internal Error during get widget id by package name");
639             DPL::Exception::DisplayKnownException(ex);
640             return WRT_ERROR_INTERNAL;
641         }
642     }
643 #ifdef __cplusplus
644 }
645 #endif