[extension] Binary messanger implementation added
[platform/core/api/webapi-plugins.git] / src / tool / desc_gentool.cc
1 #include <functional>
2 #include <iostream>
3 #include <map>
4 #include <string>
5 #include <vector>
6
7 #include <dirent.h>
8 #include <dlfcn.h>
9 #include <errno.h>
10 #include <stdio.h>
11 #include <unistd.h>
12
13 #include <common/extension.h>
14
15 static std::string prefix_ = "libtizen";
16 static std::string postfix_ = ".so";
17 static std::vector<std::string> apinamespaces = {"tizen", "xwalk"};
18
19 typedef common::Extension* (*CreateExtensionFunc)(void);
20
21 struct module_description {
22   std::string name;
23   std::string lib;
24   std::vector<std::string> entries;
25 };
26
27 static XW_Extension ext = 0;
28 static std::map<XW_Extension, module_description> descriptions;
29
30 #ifndef JSON_MINIFY
31 #define PRINT_TAB() std::cout << "\t"
32 #else
33 #define PRINT_TAB()
34 #endif
35
36 void print_json() {
37   std::cout << "[" << std::endl;
38   for (const auto& kv : descriptions) {
39     const module_description& desc = kv.second;
40
41     std::string::size_type n = desc.name.find('.');
42     std::string ns = n == std::string::npos ? desc.name : desc.name.substr(0, n);
43
44     if (std::find(apinamespaces.begin(), apinamespaces.end(), ns) == apinamespaces.end()) {
45       continue;
46     }
47
48     PRINT_TAB();
49     std::cout << "{" << std::endl;
50     PRINT_TAB();
51     PRINT_TAB();
52     std::cout << "\"name\":\"" << desc.name << "\"," << std::endl;
53     PRINT_TAB();
54     PRINT_TAB();
55     std::cout << "\"lib\":\"" << desc.lib << "\"," << std::endl;
56     PRINT_TAB();
57     PRINT_TAB();
58     std::cout << "\"entry_points\": [";
59     for (std::vector<std::string>::size_type i = 0; i < desc.entries.size(); i++) {
60       if (i != 0) {
61         std::cout << ",";
62       }
63       std::cout << "\"" << desc.entries[i] << "\"";
64     }
65     std::cout << "]" << std::endl;
66     PRINT_TAB();
67     std::cout << "}";
68     if (kv.first != ext) {
69       std::cout << ",";
70     }
71     std::cout << std::endl;
72   }
73   std::cout << "]" << std::endl;
74 }
75
76 const void* get_interface(const char* name) {
77   if (!strcmp(name, XW_CORE_INTERFACE_1)) {
78     static const XW_CoreInterface coreInterface1 = {
79         [](XW_Extension extension, const char* name) {
80           module_description* desc = &descriptions[extension];
81           desc->name = name;
82         },
83         [](XW_Extension extension, const char* api) {},
84         [](XW_Extension extension, XW_CreatedInstanceCallback created,
85            XW_DestroyedInstanceCallback destroyed) {},
86         [](XW_Extension extension, XW_ShutdownCallback shutdown_callback) {},
87         [](XW_Instance instance, void* data) {},
88         [](XW_Instance instance) -> void* { return nullptr; }};
89     return &coreInterface1;
90   }
91
92   if (!strcmp(name, XW_INTERNAL_ENTRY_POINTS_INTERFACE_1)) {
93     static const XW_Internal_EntryPointsInterface entryPointsInterface1 = {
94         [](XW_Extension extension, const char** entries) {
95           module_description* desc = &descriptions[extension];
96           for (int i = 0; entries[i]; i++) {
97             desc->entries.push_back(std::string(entries[i]));
98           }
99         }};
100     return &entryPointsInterface1;
101   }
102
103   if (!strcmp(name, XW_MESSAGING_INTERFACE_2)) {
104     static const XW_MessagingInterface_2 messagingInterface1 = {
105         [](XW_Extension extension, XW_HandleMessageCallback handle_message) {},
106         [](XW_Instance instance, const char* message) {},
107         [](XW_Extension extension,
108            XW_HandleBinaryMessageCallback handle_message) {},
109         [](XW_Instance instance, const char* message, size_t size) {}};
110     return &messagingInterface1;
111   }
112
113   if (!strcmp(name, XW_INTERNAL_SYNC_MESSAGING_INTERFACE_1)) {
114     static const XW_Internal_SyncMessagingInterface syncMessagingInterface1 = {
115         [](XW_Extension extension, XW_HandleSyncMessageCallback handle_sync_msg) {},
116         [](XW_Instance instance, const char* reply) {}};
117     return &syncMessagingInterface1;
118   }
119
120   if (!strcmp(name, XW_INTERNAL_RUNTIME_INTERFACE_1)) {
121     static const XW_Internal_RuntimeInterface_1 runtimeInterface1 = {
122         [](XW_Extension extension, const char* key, char* value, size_t vlen) {}};
123     return &runtimeInterface1;
124   }
125
126   if (!strcmp(name, XW_INTERNAL_PERMISSIONS_INTERFACE_1)) {
127     static const XW_Internal_PermissionsInterface_1 permissionsInterface1 = {
128         [](XW_Extension extension, const char* api_name) -> int { return XW_ERROR; },
129         [](XW_Extension extension, const char* perm_table) -> int { return XW_ERROR; }};
130     return &permissionsInterface1;
131   }
132
133   return NULL;
134 }
135
136 int main(int argc, char* argv[]) {
137   if (argc < 3) {
138     std::cerr << "Need tizen crosswalk path" << std::endl;
139     return -1;
140   }
141   std::string lib_path = argv[1];
142   if (lib_path.empty()) {
143     std::cerr << "Invalid libpath for tec." << std::endl;
144     return -1;
145   }
146
147   std::string tec_path = argv[2];
148   if (tec_path.empty()) {
149     std::cerr << "Invalid tizen crosswalk path" << std::endl;
150     return -1;
151   }
152
153   struct dirent** namelist;
154   int num_entries = scandir(tec_path.c_str(), &namelist, NULL, alphasort);
155   if (num_entries >= 0) {
156     for (int i = 0; i < num_entries; ++i) {
157       std::string fname = namelist[i]->d_name;
158
159       if (fname.size() >= prefix_.size() + postfix_.size() &&
160           !fname.compare(0, prefix_.size(), prefix_) &&
161           !fname.compare(fname.size() - postfix_.size(), postfix_.size(), postfix_)) {
162         std::string so_path = tec_path + "/" + fname;
163         void* handle = dlopen(so_path.c_str(), RTLD_LAZY);
164         if (handle == NULL) {
165           std::cerr << "cannot open " << so_path << std::endl;
166           char* error = dlerror();
167           std::cerr << "Error >>" << ((error == NULL) ? "NULL" : error) << std::endl;
168           return -1;
169         }
170
171         XW_Initialize_Func initialize =
172             reinterpret_cast<XW_Initialize_Func>(dlsym(handle, "XW_Initialize"));
173
174         if (!initialize) {
175           std::cerr << "Can not loading extension " << fname << std::endl;
176         } else {
177           ext++;
178           descriptions[ext] = module_description();
179           descriptions[ext].lib = lib_path + "/" + fname;
180           int ret = initialize(ext, get_interface);
181           if (ret != XW_OK) {
182             std::cerr << "Error loading extension " << fname << std::endl;
183           }
184         }
185
186         // some Shared libraries have static finalizer.
187         // __attribute__((destructor)) this gcc extension makes finalizer.
188         // if close it, it can makes segfault.
189         // True, It's shared object's problem. but we can't fix it.
190         // so don't close it in only this tool. just finish process.
191         //
192         // dlclose(handle);
193       }
194       free(namelist[i]);
195     }
196     free(namelist);
197     print_json();
198   } else {
199     perror("scandir");
200     if (errno == ENOENT) std::cerr << "path not exist : " << tec_path << std::endl;
201     return -1;
202   }
203
204   // it would be need for ignore loaded libraries destructor
205   _exit(0);
206 }