75c8a2b403b27d1772994daad511e12915839137
[platform/framework/web/crosswalk.git] / src / xwalk / extensions / browser / xwalk_extension_function_handler.h
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.
4
5 #ifndef XWALK_EXTENSIONS_BROWSER_XWALK_EXTENSION_FUNCTION_HANDLER_H_
6 #define XWALK_EXTENSIONS_BROWSER_XWALK_EXTENSION_FUNCTION_HANDLER_H_
7
8 #include <map>
9 #include <string>
10 #include "base/bind.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/values.h"
14
15 namespace xwalk {
16 namespace extensions {
17
18 class XWalkExtensionInstance;
19
20 // This struct is passed to the function handler, usually assigned to the
21 // signature of a method in JavaScript. The struct can be safely passed around.
22 class XWalkExtensionFunctionInfo {
23  public:
24   typedef base::Callback<void(scoped_ptr<base::ListValue> result)>
25       PostResultCallback;
26
27   XWalkExtensionFunctionInfo(const std::string& name,
28                              scoped_ptr<base::ListValue> arguments,
29                              const PostResultCallback& post_result_cb);
30
31   ~XWalkExtensionFunctionInfo();
32
33   // Convenience method for posting the results back to the renderer process.
34   // The object identifier is already wrapped at the |post_result_cb|. This
35   // will ultimately dispatch the result to the appropriated instance or
36   // do nothing in case the instance doesn't exist anymore. PostResult can
37   // be called from any thread.
38   void PostResult(scoped_ptr<base::ListValue> result) const {
39     post_result_cb_.Run(result.Pass());
40   };
41
42   std::string name() const {
43     return name_;
44   }
45
46   base::ListValue* arguments() const {
47     return arguments_.get();
48   }
49
50   PostResultCallback post_result_cb() const {
51     return post_result_cb_;
52   }
53
54  private:
55   std::string name_;
56   scoped_ptr<base::ListValue> arguments_;
57
58   PostResultCallback post_result_cb_;
59
60   DISALLOW_COPY_AND_ASSIGN(XWalkExtensionFunctionInfo);
61 };
62
63 // Helper for handling JavaScript method calls in the native side. Allows you to
64 // register a handler for a function with a given signature. This class takes an
65 // XWalkExtensionInstance in the constructor and should never outlive this
66 // instance.
67 class XWalkExtensionFunctionHandler {
68  public:
69   typedef base::Callback<void(
70       scoped_ptr<XWalkExtensionFunctionInfo> info)> FunctionHandler;
71
72   explicit XWalkExtensionFunctionHandler(XWalkExtensionInstance* instance);
73   ~XWalkExtensionFunctionHandler();
74
75   // Converts a raw message from the renderer to a XWalkExtensionFunctionInfo
76   // data structure and invokes HandleFunction().
77   void HandleMessage(scoped_ptr<base::Value> msg);
78
79   // Executes the handler associated to the |name| tag of the |info| argument
80   // passed as parameter.
81   bool HandleFunction(scoped_ptr<XWalkExtensionFunctionInfo> info);
82
83   // This method will register a callback to handle a message tagged as
84   // |function_name|. When invoked, the handler will get a
85   // XWalkExtensionFunctionInfo struct with the function |name| (which can be
86   // used in case a handler is in charge of more than one function). |arguments|
87   // contains the list of parameters ready to be used as input for
88   // Params::Create() generated from the IDL description of the API. The reply,
89   // if necessary, should be posted back using the PostResult() method of the
90   // XWalkExtensionFunctionInfo provided.
91   //
92   // The signature of a function handler should be like the following:
93   //
94   //   void Foobar::OnShow(scoped_ptr<XWalkExtensionFunctionInfo> info);
95   //
96   // And register them like this, preferable at the Foobar constructor:
97   //
98   //   Register("show", base::Bind(&Foobar::OnShow, base::Unretained(this)));
99   //   Register("getStuff", base::Bind(&Foobar::OnGetStuff)); // Static method.
100   //   ...
101   void Register(const std::string& function_name, FunctionHandler callback) {
102     handlers_[function_name] = callback;
103   }
104
105  private:
106   static void DispatchResult(
107       const base::WeakPtr<XWalkExtensionFunctionHandler>& handler,
108       scoped_refptr<base::MessageLoopProxy> client_task_runner,
109       const std::string& callback_id,
110       scoped_ptr<base::ListValue> result);
111
112   void PostMessageToInstance(scoped_ptr<base::Value> msg);
113
114   typedef std::map<std::string, FunctionHandler> FunctionHandlerMap;
115   FunctionHandlerMap handlers_;
116
117   XWalkExtensionInstance* instance_;
118   base::WeakPtrFactory<XWalkExtensionFunctionHandler> weak_factory_;
119
120   DISALLOW_COPY_AND_ASSIGN(XWalkExtensionFunctionHandler);
121 };
122
123 }  // namespace extensions
124 }  // namespace xwalk
125
126 #endif  // XWALK_EXTENSIONS_BROWSER_XWALK_EXTENSION_FUNCTION_HANDLER_H_