2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "extension/widget/widget.h"
23 #include "extension/xwalk/XW_Extension.h"
24 #include "extension/xwalk/XW_Extension_EntryPoints.h"
25 #include "extension/xwalk/XW_Extension_Permissions.h"
26 #include "extension/xwalk/XW_Extension_Runtime.h"
27 #include "extension/xwalk/XW_Extension_SyncMessage.h"
29 #include "extension/widget/picojson.h"
30 #include "common/logger.h"
31 #include "common/app_db.h"
32 #include "common/application_data.h"
33 #include "common/locale_manager.h"
34 #include "common/string_utils.h"
36 XW_Extension g_xw_extension = 0;
38 std::unique_ptr<wrt::ApplicationData> g_appdata;
39 const XW_CoreInterface* g_core = NULL;
40 const XW_MessagingInterface* g_messaging = NULL;
41 const XW_Internal_SyncMessagingInterface* g_sync_messaging = NULL;
42 const XW_Internal_EntryPointsInterface* g_entry_points = NULL;
43 const XW_Internal_RuntimeInterface* g_runtime = NULL;
44 extern const char kSource_widget_api[];
46 typedef void (*CmdHandler)(const picojson::value& args, picojson::object* out);
48 static void InitHandler(const picojson::value& args, picojson::object* out);
49 static void KeyHandler(const picojson::value& args, picojson::object* out);
50 static void GetItemHandler(const picojson::value& args,
51 picojson::object* out);
52 static void LengthHandler(const picojson::value& args,
53 picojson::object* out);
54 static void ClearHandler(const picojson::value& args,
55 picojson::object* out);
56 static void SetItemHandler(const picojson::value& args,
57 picojson::object* out);
58 static void RemoveHandler(const picojson::value& args,
59 picojson::object* out);
61 std::map<std::string, CmdHandler> g_handler = {
62 {"init", InitHandler},
64 {"length", LengthHandler},
65 {"clear", ClearHandler},
66 {"getItem", GetItemHandler},
67 {"setItem", SetItemHandler},
68 {"removeItem", RemoveHandler},
72 static void HandleMessage(XW_Instance instance,
76 extern "C" int32_t XW_Initialize(XW_Extension extension,
77 XW_GetInterface get_interface) {
78 g_xw_extension = extension;
79 g_core = reinterpret_cast<const XW_CoreInterface*>(
80 get_interface(XW_CORE_INTERFACE));
83 << "Can't initialize extension: error getting Core interface.";
87 g_messaging = reinterpret_cast<const XW_MessagingInterface*>(
88 get_interface(XW_MESSAGING_INTERFACE));
91 << "Can't initialize extension: error getting Messaging interface.";
96 reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
97 get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
98 if (!g_sync_messaging) {
100 << "Can't initialize extension: "
101 << "error getting SyncMessaging interface.";
105 g_entry_points = reinterpret_cast<const XW_Internal_EntryPointsInterface*>(
106 get_interface(XW_INTERNAL_ENTRY_POINTS_INTERFACE));
107 if (!g_entry_points) {
109 << "NOTE: Entry points interface not available in this version "
110 << "of Crosswalk, ignoring entry point data for extensions.\n";
114 g_runtime = reinterpret_cast<const XW_Internal_RuntimeInterface*>(
115 get_interface(XW_INTERNAL_RUNTIME_INTERFACE));
118 << "NOTE: runtime interface not available in this version "
119 << "of Crosswalk, ignoring runtime variables for extensions.\n";
123 std::vector<char> res(256, 0);
124 g_runtime->GetRuntimeVariableString(extension, "app_id", &res[0], 256);
125 g_appid = std::string(res.begin(), res.end());
126 if (g_appid.at(0) == '"') {
127 g_appid = g_appid.substr(1, g_appid.size()-2);
130 g_core->RegisterInstanceCallbacks(
132 [](XW_Instance /*instance*/){
133 if (g_appdata.get() == NULL) {
134 g_appdata.reset(new wrt::ApplicationData(g_appid));
136 wrt::Widget::GetInstance()->Initialize(g_appdata.get());
140 g_messaging->Register(g_xw_extension, [](XW_Instance instance,
141 const char* message) {
142 HandleMessage(instance, message, false);
144 g_sync_messaging->Register(g_xw_extension, [](XW_Instance instance,
145 const char* message) {
146 HandleMessage(instance, message, true);
149 g_core->SetExtensionName(g_xw_extension, "Widget");
150 const char* entry_points[] = {"widget", NULL};
151 g_entry_points->SetExtraJSEntryPoints(g_xw_extension, entry_points);
152 g_core->SetJavaScriptAPI(g_xw_extension, kSource_widget_api);
157 static void InitHandler(const picojson::value& /*args*/,
158 picojson::object* out) {
159 picojson::value result = picojson::value(picojson::object());
160 picojson::object& obj = result.get<picojson::object>();
162 auto widget_info = g_appdata->widget_info();
163 if (widget_info.get() == NULL) {
164 out->insert(std::make_pair("status", picojson::value("error")));
167 out->insert(std::make_pair("status", picojson::value("success")));
169 wrt::LocaleManager locale_manager;
170 if (!widget_info->default_locale().empty()) {
171 locale_manager.SetDefaultLocale(widget_info->default_locale());
174 // TODO(sngn.lee): should be returned localized string
175 obj["author"] = picojson::value(widget_info->author());
176 obj["description"] = picojson::value(
177 locale_manager.GetLocalizedString(widget_info->description_set()));
178 obj["name"] = picojson::value(
179 locale_manager.GetLocalizedString(widget_info->name_set()));
180 obj["shortName"] = picojson::value(
181 locale_manager.GetLocalizedString(widget_info->short_name_set()));
182 obj["version"] = picojson::value(widget_info->version());
183 obj["id"] = picojson::value(widget_info->id());
184 obj["authorEmail"] = picojson::value(widget_info->author_email());
185 obj["authorHref"] = picojson::value(widget_info->author_href());
186 obj["height"] = picojson::value(static_cast<double>(widget_info->height()));
187 obj["width"] = picojson::value(static_cast<double>(widget_info->width()));
189 out->insert(std::make_pair("result", result));
192 static void KeyHandler(const picojson::value& args, picojson::object* out) {
193 int idx = static_cast<int>(args.get("idx").get<double>());
195 if (!wrt::Widget::GetInstance()->Key(idx, &key)) {
196 out->insert(std::make_pair("status", picojson::value("error")));
199 out->insert(std::make_pair("status", picojson::value("success")));
200 out->insert(std::make_pair("result", picojson::value(key)));
203 static void GetItemHandler(const picojson::value& args,
204 picojson::object* out) {
205 const std::string& key = args.get("key").get<std::string>();
207 if (!wrt::Widget::GetInstance()->GetItem(key, &value)) {
208 out->insert(std::make_pair("status", picojson::value("error")));
211 out->insert(std::make_pair("status", picojson::value("success")));
212 out->insert(std::make_pair("result", picojson::value(value)));
215 static void LengthHandler(const picojson::value& /*args*/,
216 picojson::object* out) {
217 int length = wrt::Widget::GetInstance()->Length();
218 out->insert(std::make_pair("status", picojson::value("success")));
220 std::make_pair("result", picojson::value(static_cast<double>(length))));
223 static void ClearHandler(const picojson::value& /*args*/,
224 picojson::object* out) {
225 wrt::Widget::GetInstance()->Clear();
226 out->insert(std::make_pair("status", picojson::value("success")));
229 static void SetItemHandler(const picojson::value& args,
230 picojson::object* out) {
231 const std::string& key = args.get("key").get<std::string>();
232 const std::string& value = args.get("value").get<std::string>();
233 std::string oldvalue;
234 if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
235 out->insert(std::make_pair("result", picojson::value(oldvalue)));
237 out->insert(std::make_pair("result", picojson::value()));
239 wrt::Widget::GetInstance()->SetItem(key, value);
240 out->insert(std::make_pair("status", picojson::value("success")));
243 static void RemoveHandler(const picojson::value& args,
244 picojson::object* out) {
245 const std::string& key = args.get("key").get<std::string>();
246 std::string oldvalue;
247 if (wrt::Widget::GetInstance()->GetItem(key, &oldvalue)) {
248 out->insert(std::make_pair("result", picojson::value(oldvalue)));
250 out->insert(std::make_pair("result", picojson::value()));
252 wrt::Widget::GetInstance()->RemoveItem(key);
253 out->insert(std::make_pair("status", picojson::value("success")));
257 static void HandleMessage(XW_Instance instance,
260 picojson::value value;
262 picojson::parse(value, message, message + strlen(message), &err);
264 LOGGER(ERROR) << "Ignoring message. " << err;
268 if (!value.is<picojson::object>()) {
269 LOGGER(ERROR) << "Ignoring message. It is not an object.";
273 std::string cmd = value.get("cmd").to_str();
274 // check for args in JSON message
275 const picojson::value& args = value.get("args");
276 picojson::value result = picojson::value(picojson::object());
278 auto handler = g_handler.find(cmd);
279 if (handler != g_handler.end()) {
280 handler->second(args, &result.get<picojson::object>());
282 result.get<picojson::object>().insert(
283 std::make_pair("status", picojson::value("error")));
287 g_sync_messaging->SetSyncReply(instance, result.serialize().c_str());
294 const char* kDbInitedCheckKey = "__WRT_DB_INITED__";
295 const char* kDBPublicSection = "public";
296 const char* kDBPrivateSection = "private";
300 Widget* Widget::GetInstance() {
301 static Widget instance;
310 void Widget::Initialize(const ApplicationData* appdata) {
311 AppDB* db = AppDB::GetInstance();
312 if (db->HasKey(kDBPrivateSection, kDbInitedCheckKey))
314 if (appdata->widget_info() == NULL)
317 auto preferences = appdata->widget_info()->preferences();
318 auto it = preferences.begin();
319 for ( ; it != preferences.end(); ++it) {
320 db->Set(kDBPublicSection,
324 db->Set(kDBPrivateSection, kDbInitedCheckKey, "true");
327 int Widget::Length() {
328 AppDB* db = AppDB::GetInstance();
329 std::list<std::string> list;
330 db->GetKeys(kDBPublicSection, &list);
334 bool Widget::Key(int idx, std::string* key) {
335 AppDB* db = AppDB::GetInstance();
336 std::list<std::string> list;
337 db->GetKeys(kDBPublicSection, &list);
339 auto it = list.begin();
340 for ( ; it != list.end() && idx >= 0; ++it) {
350 bool Widget::GetItem(const std::string& key, std::string* value) {
351 AppDB* db = AppDB::GetInstance();
352 if (!db->HasKey(kDBPublicSection, key))
354 *value = db->Get(kDBPublicSection, key);
358 bool Widget::SetItem(const std::string& key, const std::string& value) {
359 AppDB* db = AppDB::GetInstance();
360 db->Set(kDBPublicSection, key, value);
364 bool Widget::RemoveItem(const std::string& key) {
365 AppDB* db = AppDB::GetInstance();
366 if (!db->HasKey(kDBPublicSection, key))
368 db->Remove(kDBPublicSection, key);
372 void Widget::Clear() {
373 AppDB* db = AppDB::GetInstance();
374 std::list<std::string> list;
375 db->GetKeys(kDBPublicSection, &list);
376 auto it = list.begin();
377 for ( ; it != list.end(); ++it) {
378 db->Remove(kDBPublicSection, *it);