fced9c960fa1282cfe3222dd5cccee06b984b63e
[platform/framework/web/web-provider.git] / src / API / web_provider_plugin_info.cpp
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Flora License, Version 1.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://floralicense.org/license/
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    web_provider_livebox_info.cpp 
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  */
20
21
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <dirent.h>
25 #include <string>
26 #include <cstring>
27 #include <cstdlib>
28 #include <list>
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <json-glib/json-glib.h>
32 #include <Core/Util/Log.h>
33 #include "web_provider_plugin_info.h"
34 #include <memory>
35
36 // static functions
37 static web_provider_plugin_info* get_parsed_json_data(std::string& configPath);
38 static bool web_provider_plugin_release_info(web_provider_plugin_info* info);
39
40 static const std::string installedPluginDirPath("/usr/lib/web-provider/");
41
42 // Json's content for plugin is the following (example)
43 // {
44 //      "type" : "clip",
45 //      "path" : "/usr/lib/web-provider/libweb-provider-plugin-clipbox.so",
46 //      "service_boxid" : "org.tizen.browser"
47 // }
48 //
49 // "service_boxid" is only optional member in json file
50
51 static const std::string jsonMemberType("type");
52 static const std::string jsonMemberPath("path");
53 static const std::string jsonMemberBoxId("service_boxid");
54 static const std::string jsonMemberBoxScrollable("box_scrollable");
55
56 static const std::string jsonValueBoolTrue("true");
57 static const std::string jsonValueBoolFalse("false");
58 static const std::string jsonFileExtension(".json");
59
60 web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count)
61 {
62     LogD("enter");
63
64     // open directory of web provider plugin
65     DIR* dir = opendir(installedPluginDirPath.c_str());
66     if (!dir) {
67         LogD("failed to open directory for web livebox plugins");
68         *count = 0;
69         return NULL;
70     }
71
72     // read plugin directory and store plugin config path
73     std::list<std::string> configList;
74     struct dirent* entry;
75     struct stat configStat;
76     std::string configPath;
77     while (entry = readdir(dir)) {
78         if (!strcmp(entry->d_name, ".") || 
79                 !strcmp(entry->d_name, "..")) {
80             continue;
81         }
82
83         configPath = installedPluginDirPath + entry->d_name;
84
85         if (stat(configPath.c_str(), &configStat) < 0) {
86             LogD("Failed to open file");
87             continue;
88         }
89
90         if (S_ISDIR(configStat.st_mode)) {
91             continue;
92         }
93
94         LogD("config file: %s", configPath.c_str());
95         configList.push_back(configPath);
96     }
97     // close directory of web provider plugin
98     closedir(dir);
99
100     if (configList.size() == 0) {
101         *count = 0;
102         return NULL;
103     }
104
105     // parse available each plugin json file
106     std::list<web_provider_plugin_info*> pluginList;
107     for (auto it = configList.begin(); 
108             it != configList.end(); it++) {
109         web_provider_plugin_info* info = get_parsed_json_data(*it) ;
110         if (!info) {
111             continue;
112         }
113
114         pluginList.push_back(info);
115     }
116     *count = pluginList.size();
117     LogD("read plugin count: %d", *count);
118
119     // c style array allocation for return of result
120     web_provider_plugin_info** info_list =
121         static_cast<web_provider_plugin_info**>(
122                 malloc((*count) * sizeof(web_provider_plugin_info*)));
123
124     // copy from members in std::list to one in c style array
125     int idx = 0;
126     for (auto it = pluginList.begin();
127             it != pluginList.end(); it++) {
128         LogD("type: %s", (*it)->type);
129         LogD("path: %s", (*it)->path);
130         if ((*it)->service_boxid) {
131             LogD("service_boxid: %s", (*it)->service_boxid);
132         }
133         info_list[idx] = *it;
134         idx++;
135     }
136
137     LogD("success to return plugin information");
138     return info_list;
139 }
140
141 void web_provider_plugin_release_installed_list(
142         web_provider_plugin_info** info_list, 
143         int count)
144 {
145     if (!info_list) {
146         return;
147     }
148
149     for (int i = 0; i < count; i++) {
150         web_provider_plugin_release_info(info_list[i]);
151     }
152 }
153
154 int web_provider_plugin_get_box_scrollable(const char* plugin_type)
155 {
156     if (!plugin_type) {
157         return -1;
158     }
159
160     std::string configPath;
161     configPath = installedPluginDirPath;
162     configPath += plugin_type;
163     configPath += jsonFileExtension;
164     web_provider_plugin_info* info = get_parsed_json_data(configPath);
165
166     if (!info) {
167         return -1;
168     }
169     int ret = info->box_scrollable;
170     web_provider_plugin_release_info(info);
171
172     LogD("box_scrollable: %d", ret);
173     return ret;
174 }
175
176 static web_provider_plugin_info* get_parsed_json_data(std::string& configPath)
177 {
178     g_type_init();
179
180     web_provider_plugin_info* info;
181     JsonParser* parser = json_parser_new();
182     GError* error = NULL;
183
184     json_parser_load_from_file(parser, configPath.c_str(), &error);
185     if (error) {
186         LogD("failed to parse json file: %s -> %s", configPath.c_str(), error->message);
187         g_error_free(error);
188         g_object_unref(parser);
189         return NULL;
190     }
191
192     JsonNode* root = json_parser_get_root(parser);
193     JsonObject* object = json_node_get_object(root);
194     
195     // check if type member exists on this json file
196     const char* type = 
197         static_cast<const char*>(
198             json_object_get_string_member(object, jsonMemberType.c_str()));
199
200     const char* path = 
201         static_cast<const char*>(
202             json_object_get_string_member(object, jsonMemberPath.c_str()));
203
204     if (!type || !path) {
205         LogD("mandatory members don't exist");
206         g_error_free(error);
207         g_object_unref(parser);
208         return NULL;
209     }
210
211     // allocate instance of plugin info struct
212     info = static_cast<web_provider_plugin_info*>(
213             malloc(sizeof(web_provider_plugin_info)));
214     memset(info, 0, sizeof(web_provider_plugin_info));
215
216     info->type = strdup(type);
217     info->path = strdup(path);
218
219     gboolean hasBoxId = json_object_has_member(object, jsonMemberBoxId.c_str());
220     if (hasBoxId == TRUE) {
221         const char* boxId = 
222             static_cast<const char*>(
223                 json_object_get_string_member(object, jsonMemberBoxId.c_str()));
224         if (boxId) {
225             info->service_boxid = strdup(boxId);
226         }
227     }
228
229     gboolean hasBoxScrollable =
230         json_object_has_member(object, jsonMemberBoxScrollable.c_str());
231     if (hasBoxScrollable == TRUE) {
232         const char* boxScrollable =
233             static_cast<const char*>(
234                 json_object_get_string_member(object, jsonMemberBoxScrollable.c_str()));
235         if (boxScrollable && (jsonValueBoolTrue == boxScrollable)) {
236             info->box_scrollable = 1;
237         } else {
238             info->box_scrollable = 0;
239         }
240     }
241
242     LogD("type: %s", info->type);
243     LogD("path: %s", info->path);
244     if (info->service_boxid) {
245         LogD("service_boxid: %s", info->service_boxid);
246     }
247     LogD("box_scrollable: %d", info->box_scrollable);
248
249     json_node_free(root);
250     g_error_free(error);
251     g_object_unref(parser);
252
253     return info; 
254 }
255
256 bool web_provider_plugin_release_info(web_provider_plugin_info* info)
257 {
258     LogD("enter");
259     if (!info) {
260         LogD("empty struct");
261         return false;
262     }
263
264     // only members with buffer are released
265     delete info->type;
266     delete info->path;
267     delete info->service_boxid;
268     delete info;
269
270     return true;
271 }