1 // Copyright (c) 2013 Intel Corporation. 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.
5 #include "xwalk/extensions/browser/xwalk_extension_function_handler.h"
7 #include "base/location.h"
8 #include "xwalk/extensions/common/xwalk_external_instance.h"
11 namespace extensions {
13 XWalkExtensionFunctionInfo::XWalkExtensionFunctionInfo(
14 const std::string& name,
15 scoped_ptr<base::ListValue> arguments,
16 const PostResultCallback& post_result_cb)
18 arguments_(arguments.Pass()),
19 post_result_cb_(post_result_cb) {}
21 XWalkExtensionFunctionInfo::~XWalkExtensionFunctionInfo() {}
23 XWalkExtensionFunctionHandler::XWalkExtensionFunctionHandler(
24 XWalkExtensionInstance* instance)
25 : instance_(instance),
26 weak_factory_(this) {}
28 XWalkExtensionFunctionHandler::~XWalkExtensionFunctionHandler() {}
30 void XWalkExtensionFunctionHandler::HandleMessage(scoped_ptr<base::Value> msg) {
31 base::ListValue* args;
32 if (!msg->GetAsList(&args) || args->GetSize() < 2) {
33 // FIXME(tmpsantos): This warning could be better if the Context had a
34 // pointer to the Extension. We could tell what extension sent the
36 LOG(WARNING) << "Invalid number of arguments.";
40 // The first parameter stands for the function signature.
41 std::string function_name;
42 if (!args->GetString(0, &function_name)) {
43 LOG(WARNING) << "The function name is not a string.";
47 // The second parameter stands for callback id, the remaining
48 // ones are the function arguments.
49 std::string callback_id;
50 if (!args->GetString(1, &callback_id)) {
51 LOG(WARNING) << "The callback id is not a string.";
55 // We reuse args to pass the extra arguments to the handler, so remove
56 // function_name and callback_id from it.
57 args->Remove(0, NULL);
58 args->Remove(0, NULL);
60 scoped_ptr<XWalkExtensionFunctionInfo> info(
61 new XWalkExtensionFunctionInfo(
63 make_scoped_ptr(static_cast<base::ListValue*>(msg.release())),
64 base::Bind(&XWalkExtensionFunctionHandler::DispatchResult,
65 weak_factory_.GetWeakPtr(),
66 base::MessageLoopProxy::current(),
69 if (!HandleFunction(info.Pass())) {
70 DLOG(WARNING) << "Function not registered: " << function_name;
75 bool XWalkExtensionFunctionHandler::HandleFunction(
76 scoped_ptr<XWalkExtensionFunctionInfo> info) {
77 FunctionHandlerMap::iterator iter = handlers_.find(info->name());
78 if (iter == handlers_.end())
81 iter->second.Run(info.Pass());
87 void XWalkExtensionFunctionHandler::DispatchResult(
88 const base::WeakPtr<XWalkExtensionFunctionHandler>& handler,
89 scoped_refptr<base::MessageLoopProxy> client_task_runner,
90 const std::string& callback_id,
91 scoped_ptr<base::ListValue> result) {
94 if (client_task_runner != base::MessageLoopProxy::current()) {
95 client_task_runner->PostTask(FROM_HERE,
96 base::Bind(&XWalkExtensionFunctionHandler::DispatchResult,
100 base::Passed(&result)));
104 if (callback_id.empty()) {
105 DLOG(WARNING) << "Sending a reply with an empty callback id has no"
106 "practical effect. This code can be optimized by not creating "
107 "and not posting the result.";
111 // Prepend the callback id to the list, so the handlers
112 // on the JavaScript side know which callback should be evoked.
113 result->Insert(0, new base::StringValue(callback_id));
116 handler->PostMessageToInstance(result.PassAs<base::Value>());
119 void XWalkExtensionFunctionHandler::PostMessageToInstance(
120 scoped_ptr<base::Value> msg) {
121 instance_->PostMessageToJS(msg.Pass());
124 } // namespace extensions