tizen 2.4 release
[framework/web/wrt-plugins-common.git] / src / xwalk-module / extension_manager.cpp
1 // Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extension_manager.h"
6
7 #include <glob.h>
8 #include <dlog.h>
9 #include <dpl/log/secure_log.h>
10 #include <memory>
11 #include <iostream>
12 #include <fstream>
13
14 #include "runtime_variable_provider.h"
15 #include "picojson.h"
16
17
18 namespace wrt {
19 namespace xwalk {
20
21 namespace {
22 const char kExtensionDir[] = "/usr/lib/tizen-extensions-crosswalk";
23 const char kExtensionPrefix[] = "lib";
24 const char kExtensionSuffix[] = ".so";
25 const char kExtensionMetadataSuffix[] = ".json";
26
27 }
28
29 ExtensionManager::ExtensionManager() {
30 }
31
32 ExtensionManager::~ExtensionManager() {
33 }
34
35 ExtensionManager* ExtensionManager::GetInstance() {
36   static ExtensionManager self;
37   return &self;
38 }
39
40 void ExtensionManager::RegisterExtensionsByMetadata(
41     RuntimeVariableProvider* provider, const std::string& metafile_path) {
42   _D("path : [%s]", metafile_path.c_str());
43   std::ifstream metafile(metafile_path.c_str());
44   if (!metafile.is_open()) {
45     LOGE("Can't open plugin metadata file");
46     return;
47   }
48
49   picojson::value metadata;
50   metafile >> metadata;
51   if (metadata.is<picojson::array>()) {
52     auto& plugins = metadata.get<picojson::array>();
53     for (auto plugin = plugins.begin(); plugin != plugins.end(); ++plugin) {
54       if (!plugin->is<picojson::object>())
55         continue;
56
57       std::string name = plugin->get("name").to_str();
58       std::string lib = plugin->get("lib").to_str();
59       if (lib.at(0) != '/') {
60         lib = std::string(kExtensionDir) + "/" + lib;
61       }
62       std::vector<std::string> entries;
63       auto& entry_points_value = plugin->get("entry_points");
64       if (entry_points_value.is<picojson::array>()) {
65         auto& entry_points = entry_points_value.get<picojson::array>();
66         for (auto entry = entry_points.begin(); entry != entry_points.end();
67              ++entry) {
68           entries.push_back(entry->to_str());
69         }
70       } else {
71         LOGE("there is no entry points");
72       }
73       Extension* extension = new Extension(lib, name, entries, provider);
74       RegisterExtension(extension);
75     }
76   } else {
77     LOGE("Not plugin metadata");
78     _E("%s is not plugin metadata", metafile_path.c_str());
79   }
80   metafile.close();
81 }
82
83 void ExtensionManager::RegisterExtensionsByMetadata(
84     RuntimeVariableProvider* provider) {
85   std::string extension_path(kExtensionDir);
86   extension_path.append("/");
87   extension_path.append("*");
88   extension_path.append(kExtensionMetadataSuffix);
89
90   LOGD("Register Extension directory");
91   _D("path : [%s]", extension_path.c_str());
92
93   glob_t glob_result;
94   glob(extension_path.c_str(), GLOB_TILDE, NULL, &glob_result);
95   for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
96     RegisterExtensionsByMetadata(provider, glob_result.gl_pathv[i]);
97   }
98   if (glob_result.gl_pathc == 0) {
99     RegisterExtensionsInDirectory(provider);
100   }
101 }
102
103
104 void ExtensionManager::RegisterExtensionsInDirectory(RuntimeVariableProvider* provider) {
105   std::string extension_path(kExtensionDir);
106   extension_path.append("/");
107   extension_path.append(kExtensionPrefix);
108   extension_path.append("*");
109   extension_path.append(kExtensionSuffix);
110
111   LOGD("Register Extension directory");
112   _D("path : [%s]", extension_path.c_str());
113
114   glob_t glob_result;
115   glob(extension_path.c_str(), GLOB_TILDE, NULL, &glob_result);
116   for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
117     Extension* extension = new Extension(glob_result.gl_pathv[i], provider);
118     if (extension->Initialize()) {
119       RegisterExtension(extension);
120     }
121   }
122 }
123
124 bool ExtensionManager::RegisterExtension(Extension* extension) {
125   LOGD("========== << RegisterExtension >> ENTER ==========");
126   if (!extension)
127     return false;
128
129   std::string name = extension->name();
130
131   LOGD("Register Extension name : [%s]", name.c_str());
132   if (extension_symbols_.find(name) != extension_symbols_.end()) {
133     LOGW("Ignoring extension with name already registred. '%s'", name.c_str());
134     return false;
135   }
136
137   std::vector<std::string>& entry_points = extension->entry_points();
138   std::vector<std::string>::iterator iter;
139   for (iter = entry_points.begin(); iter != entry_points.end(); ++iter) {
140     if (extension_symbols_.find(*iter) != extension_symbols_.end()) {
141       LOGW("Ignoring extension with entry_point already registred. '%s'", (*iter).c_str());
142       return false;
143     }
144   }
145
146   for (iter = entry_points.begin(); iter != entry_points.end(); ++iter) {
147     extension_symbols_.insert(*iter);
148   }
149
150   extension_symbols_.insert(name);
151   extensions_[name] = extension;
152
153   LOGD("========== << RegisterExtension >> END ==========");
154   return true;
155 }
156
157
158 } // namespace xwalk
159 } // namespace wrt