tizen beta release
[framework/web/wrt-installer.git] / src / pkg-manager / backendlib.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  *
18  *
19  * @file       backendlib.cpp
20  * @author     Soyoung Kim (sy037.kim@samsung.com)
21  * @version    0.1
22  * @brief      This is implementation file for providing widget information
23  *             to package manager
24  */
25 #include "package-manager-plugin.h"
26 #include <dlog.h>
27 #include <dpl/wrt-dao-ro/global_config.h>
28 #include <dpl/ace-dao-rw/AceDAO.h>
29 #include <vcore/VCore.h>
30 #include <dpl/wrt-dao-ro/WrtDatabase.h>
31 #include <dpl/wrt-dao-rw/widget_dao.h>
32 #include <dpl/wrt-dao-ro/feature_dao_read_only.h>
33 #include <dpl/wrt-dao-ro/widget_config.h>
34 #include <string>
35 #include <dpl/db/sql_connection.h>
36 #include <dpl/log/log.h>
37 #include <dpl/foreach.h>
38 #include <dpl/ace-dao-ro/wrt_db_types.h>
39 #include <dpl/utils/folder_size.h>
40
41 using namespace WrtDB;
42
43 #undef TRUE
44 #undef FALSE
45 #define TRUE 0
46 #define FALSE -1
47 #define GET_DIRECTORY_SIZE_KB(x)    (x)/1024
48
49 #ifdef __cplusplus
50 extern "C"
51 {
52 #endif
53
54 class DatabaseConnection
55 {
56   public:
57     void AttachDatabase()
58     {
59         WrtDB::WrtDatabase::attachToThread();
60     }
61
62     void DetachDatabase()
63     {
64         WrtDB::WrtDatabase::detachFromThread();
65     }
66 };
67
68 static DPL::ScopedPtr<DatabaseConnection> g_databaseConnection;
69
70 static void pkg_native_plugin_on_unload();
71 static int pkg_plugin_app_is_installed(const char *pkg_name);
72 static int pkg_plugin_get_installed_apps_list(const char *category,
73         const char *option, package_manager_pkg_info_t **list, int *count);
74 static int pkg_plugin_get_app_detail_info(const char *pkg_name,
75         package_manager_pkg_detail_info_t *pkg_detail_info);
76 static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path,
77         package_manager_pkg_detail_info_t *pkg_detail_info);
78
79 static int is_connected()
80 {
81     if (NULL == g_databaseConnection) {
82         Try {
83             g_databaseConnection.Reset(new DatabaseConnection());
84             g_databaseConnection->AttachDatabase();
85         }
86         Catch (DPL::DB::SqlConnection::Exception::Base) {
87             LogDebug("Fail to connect DB");
88             return FALSE;
89         }
90     }
91
92     return TRUE;
93 }
94
95 static void pkg_native_plugin_on_unload()
96 {
97     LogDebug("pkg_native_plugin_unload() is called");
98 }
99
100 static int pkg_plugin_app_is_installed(const char *pkg_name)
101 {
102     LogDebug("pkg_plugin_app_is_installed() is called");
103
104     if (FALSE == is_connected()) {
105         LogError("Fail DB Connect");
106         return FALSE;
107     }
108
109     Try {
110         if (WidgetDAOReadOnly::isWidgetInstalled(
111                 DPL::FromUTF8String(pkg_name))) {
112             return TRUE;
113         }
114     } Catch(DPL::DB::SqlConnection::Exception::Base) {
115         LogDebug("Databas Error");
116         return FALSE;
117     }
118
119     LogDebug("Widget Not Found");
120     return FALSE;
121 }
122
123 static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
124         const char * /*option*/, package_manager_pkg_info_t **list, int *count)
125 {
126     LogDebug("pkg_plugin_get_installed_apps_list() is called");
127
128     package_manager_pkg_info_t *pkg_list = NULL;
129     package_manager_pkg_info_t *pkg_last = NULL;
130
131     Try {
132         if (FALSE == is_connected()) {
133             LogError("Fail DB Connect");
134             return FALSE;
135         }
136
137         WidgetHandleList hndlList = WidgetDAO::getHandleList();
138         *count = 0;
139
140         FOREACH(iterator, hndlList) {
141             package_manager_pkg_info_t *pkg_info =
142                 static_cast<package_manager_pkg_info_t*>
143                 (malloc(sizeof(package_manager_pkg_info_t)));
144             if (NULL == pkg_info) {
145                 LogError("Error in malloc");
146                 return FALSE;
147             }
148
149             if (NULL == pkg_list) {
150                 pkg_list = pkg_info;
151                 pkg_last = pkg_info;
152             } else {
153                 pkg_last->next = pkg_info;
154             }
155
156             WidgetDAO widget(*iterator);
157             DPL::Optional<DPL::String> pkgname = widget.getPkgname();
158             strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
159             if(!pkgname.IsNull()) {
160                 snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s",
161                         DPL::ToUTF8String(*pkgname).c_str());
162             }
163
164             DPL::Optional<DPL::String> version = widget.getVersion();
165             if (!version.IsNull()) {
166                 strncpy(pkg_info->version,
167                         DPL::ToUTF8String(*version).c_str(),
168                         PKG_VERSION_STRING_LEN_MAX);
169             }
170
171             (*count)++;
172             pkg_last = pkg_info;
173         }
174         *list = pkg_list;
175     }
176     Catch (WidgetDAO::Exception::DatabaseError) {
177         LogError("Database Error");
178         return FALSE;
179     }
180     return TRUE;
181 }
182
183 static int pkg_plugin_get_app_detail_info(const char *pkg_name,
184         package_manager_pkg_detail_info_t *pkg_detail_info)
185 {
186     LogDebug("pkg_plugin_get_app_detail_info() is called");
187
188     Try {
189         if (FALSE == is_connected()) {
190             LogError("Fail DB Connect");
191             return FALSE;
192         }
193
194         int handle = WidgetDAOReadOnly::getHandle(
195                         DPL::FromUTF8String(pkg_name));
196         WidgetDAO widget(handle);
197
198         DPL::Optional<DPL::String> version = widget.getVersion();
199         DPL::Optional<DPL::String> id = widget.getGUID();
200         DPL::Optional<DPL::String> locale = widget.getDefaultlocale();
201
202         if (!version.IsNull()) {
203             strncpy(pkg_detail_info->version,
204                     DPL::ToUTF8String(*version).c_str(),
205                     PKG_VERSION_STRING_LEN_MAX);
206         }
207         snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%d",
208                handle);
209         WidgetLocalizedInfo localizedInfo;
210
211         if (locale.IsNull()) {
212             LogError("is NULL");
213             DPL::String languageTag(L"");
214             localizedInfo = widget.getLocalizedInfo(languageTag);
215         } else {
216             localizedInfo = widget.getLocalizedInfo(*locale);
217         }
218         DPL::Optional<DPL::String> desc(localizedInfo.description);
219
220         if (!desc.IsNull()) {
221             strncpy(pkg_detail_info->pkg_description,
222                     DPL::ToUTF8String(*desc).c_str(),
223                     PKG_VALUE_STRING_LEN_MAX);
224         }
225         strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
226         strncpy(pkg_detail_info->pkg_name, pkg_name, PKG_NAME_STRING_LEN_MAX);
227
228         /* set installed time */
229         pkg_detail_info->installed_time = widget.getInstallTime();
230
231         /* set Widget size */
232         DPL::String pkgName = DPL::FromUTF8String(pkg_name);
233         std::string installPath = WidgetConfig::GetWidgetBasePath(pkgName);
234         std::string persistentPath =
235             WidgetConfig::GetWidgetPersistentStoragePath(pkgName);
236         std::string tempPath =
237             WidgetConfig::GetWidgetTemporaryStoragePath(pkgName);
238         installPath += "/";
239         tempPath += "/";
240         persistentPath += "/";
241
242         size_t installedSize = Utils::getFolderSize(installPath);
243         size_t persistentSize = Utils::getFolderSize(persistentPath);
244         size_t appSize = installedSize - persistentSize;
245         size_t dataSize = persistentSize + Utils::getFolderSize(tempPath);
246
247         pkg_detail_info->installed_size = GET_DIRECTORY_SIZE_KB(installedSize);
248         pkg_detail_info->app_size = GET_DIRECTORY_SIZE_KB(appSize);
249         pkg_detail_info->data_size = GET_DIRECTORY_SIZE_KB(dataSize);
250     }
251     Catch (WidgetDAO::Exception::DatabaseError) {
252         LogError("Database Error");
253         return FALSE;
254     }
255     return TRUE;
256 }
257
258 static int pkg_plugin_get_app_detail_info_from_package(
259         const char * /*pkg_path*/,
260         package_manager_pkg_detail_info_t * /*pkg_detail_info*/)
261 {
262     LogDebug("pkg_plugin_get_app_detail_info_from_package() is called");
263
264     return TRUE;
265 }
266
267 __attribute__ ((visibility("default")))
268 int pkg_plugin_on_load(pkg_plugin_set *set)
269 {
270     DPL::Log::LogSystemSingleton::Instance().SetTag("WGT-BACKLIB");
271     if (NULL == set) {
272         return FALSE;
273     }
274     memset(set, 0x00, sizeof(pkg_plugin_set));
275
276     set->plugin_on_unload = pkg_native_plugin_on_unload;
277     set->pkg_is_installed = pkg_plugin_app_is_installed;
278     set->get_installed_pkg_list = pkg_plugin_get_installed_apps_list;
279     set->get_pkg_detail_info = pkg_plugin_get_app_detail_info;
280     set->get_pkg_detail_info_from_package =
281         pkg_plugin_get_app_detail_info_from_package;
282
283     return TRUE;
284 }
285
286 #ifdef __cplusplus
287 }
288 #endif