[Release] livebox.web-provider-1.9
[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
39 static const std::string installedPluginDirPath("/usr/lib/web-provider/");
40
41 // Json's content for plugin is the following (example)
42 // {
43 //      "type" : "clip",
44 //      "path" : "/usr/lib/web-provider/libweb-provider-plugin-clipbox.so"
45 //      "service_boxid" : "org.tizen.browser"
46 // }
47 //
48 // "service_boxid" is only optional member in json file
49
50 static const std::string jsonMemberType("type");
51 static const std::string jsonMemberPath("path");
52 static const std::string jsonMemberBoxId("service_boxid");
53
54 web_provider_plugin_info** web_provider_plugin_get_installed_list(int* count)
55 {
56     std::unique_ptr<DIR, int(*)(DIR*)> dir (opendir(installedPluginDirPath.c_str()), closedir);
57     if (!dir) {
58         LogD("failed to open directory for web livebox plugins");
59         *count = 0;
60         return NULL;
61     }
62
63     // read plugin directory and store plugin config path
64     std::list<std::string> configList;
65     struct dirent* entry;
66     struct stat configStat;
67     std::string configPath;
68     while ((entry = readdir(dir.get()))) {
69         if (!strcmp(entry->d_name, ".") || 
70                 !strcmp(entry->d_name, "..")) {
71             continue;
72         }
73
74         configPath = installedPluginDirPath + entry->d_name;
75
76         if (stat(configPath.c_str(), &configStat) < 0) {
77             LogD("Failed to open file");
78             continue;
79         }
80
81         if (S_ISDIR(configStat.st_mode)) {
82             continue;
83         }
84
85         LogD("config file: %s", configPath.c_str());
86         configList.push_back(configPath);
87     }
88
89     if (configList.size() == 0) {
90         *count = 0;
91         return NULL;
92     }
93
94     // parse available each plugin json file
95     std::list<web_provider_plugin_info*> pluginList;
96     for (auto it = configList.begin(); 
97             it != configList.end(); it++) {
98         web_provider_plugin_info* info = get_parsed_json_data(*it) ;
99         if (!info) {
100             continue;
101         }
102
103         pluginList.push_back(info);
104     }
105     *count = pluginList.size();
106     LogD("read plugin count: %d", *count);
107
108     // c style array allocation for return of result
109     web_provider_plugin_info** info_list =
110         static_cast<web_provider_plugin_info**>(
111                 malloc((*count) * sizeof(web_provider_plugin_info*)));
112
113     // copy from members in std::list to one in c style array
114     int idx = 0;
115     for (auto it = pluginList.begin();
116             it != pluginList.end(); it++) {
117         LogD("type: %s", (*it)->type);
118         LogD("path: %s", (*it)->path);
119         if ((*it)->service_boxid) {
120             LogD("service_boxid: %s", (*it)->service_boxid);
121         }
122         info_list[idx] = *it;
123         idx++;
124     }
125
126     LogD("success to return plugin information");
127     return info_list;
128 }
129
130 void web_provider_plugin_release_installed_list(
131         web_provider_plugin_info** info_list, 
132         int count)
133 {
134     if (!info_list) {
135         return;
136     }
137
138     for (int i = 0; i < count; i++) {
139         if (info_list[i]) {
140             if (info_list[i]->type) {
141                 delete[] info_list[i]->type;
142             }
143             if (info_list[i]->path) {
144                 delete[] info_list[i]->path;
145             }
146             if (info_list[i]->service_boxid) {
147                 delete[] info_list[i]->service_boxid;
148             }
149         }
150     }
151     if (info_list) {
152         delete[] info_list;
153     }
154 }
155
156 static web_provider_plugin_info* get_parsed_json_data(std::string& configPath)
157 {
158     g_type_init();
159
160     web_provider_plugin_info* info;
161     JsonParser* parser = json_parser_new();
162     GError* error = NULL;
163
164     json_parser_load_from_file(parser, configPath.c_str(), &error);
165     if (error) {
166         LogD("failed to parse json file: %s -> %s", configPath.c_str(), error->message);
167         g_error_free(error);
168         g_object_unref(parser);
169         return NULL;
170     }
171
172     JsonNode* root = json_parser_get_root(parser);
173     JsonObject* object = json_node_get_object(root);
174     
175     // check if type member exists on this json file
176     const char* type = 
177         static_cast<const char*>(
178             json_object_get_string_member(object, jsonMemberType.c_str()));
179
180     const char* path = 
181         static_cast<const char*>(
182             json_object_get_string_member(object, jsonMemberPath.c_str()));
183
184     if (!type || !path) {
185         LogD("mandatory members don't exist");
186         g_error_free(error);
187         g_object_unref(parser);
188         return NULL;
189     }
190
191     // allocate instance of plugin info struct
192     info = static_cast<web_provider_plugin_info*>(
193             malloc(sizeof(web_provider_plugin_info)));
194     memset(info, 0, sizeof(web_provider_plugin_info));
195
196     info->type = strdup(type);
197     info->path = strdup(path);
198
199     gboolean hasBoxId = json_object_has_member(object, jsonMemberBoxId.c_str());
200     if (hasBoxId == TRUE) {
201         const char* boxId = 
202             static_cast<const char*>(
203                 json_object_get_string_member(object, jsonMemberBoxId.c_str()));
204         if (boxId) {
205             info->service_boxid = strdup(boxId);
206         }
207     }
208
209     LogD("type: %s", info->type);
210     LogD("path: %s", info->path);
211     if (info->service_boxid) {
212         LogD("service_boxid: %s", info->service_boxid);
213     }
214
215     json_node_free(root);
216     g_error_free(error);
217     g_object_unref(parser);
218
219     return info; 
220 }