• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. 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 CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
7 #pragma once
8 
9 #include <string>
10 #include <list>
11 
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "chrome/browser/extensions/extension_function_dispatcher.h"
15 
16 class ExtensionFunctionDispatcher;
17 class ListValue;
18 class Profile;
19 class QuotaLimitHeuristic;
20 class Value;
21 
22 #define EXTENSION_FUNCTION_VALIDATE(test) do { \
23     if (!(test)) { \
24       bad_message_ = true; \
25       return false; \
26     } \
27   } while (0)
28 
29 #define EXTENSION_FUNCTION_ERROR(error) do { \
30     error_ = error; \
31     bad_message_ = true; \
32     return false; \
33   } while (0)
34 
35 #define DECLARE_EXTENSION_FUNCTION_NAME(name) \
36   public: static const char* function_name() { return name; }
37 
38 // Abstract base class for extension functions the ExtensionFunctionDispatcher
39 // knows how to dispatch to.
40 class ExtensionFunction : public base::RefCountedThreadSafe<ExtensionFunction> {
41  public:
42   ExtensionFunction();
43 
44   // Specifies the name of the function.
set_name(const std::string & name)45   void set_name(const std::string& name) { name_ = name; }
name()46   const std::string name() const { return name_; }
47 
48   // Set the profile which contains the extension that has originated this
49   // function call.
set_profile(Profile * profile)50   void set_profile(Profile* profile) { profile_ = profile; }
profile()51   Profile* profile() const { return profile_; }
52 
53   // Set the id of this function call's extension.
set_extension_id(std::string extension_id)54   void set_extension_id(std::string extension_id) {
55     extension_id_ = extension_id;
56   }
extension_id()57   std::string extension_id() const { return extension_id_; }
58 
59   // Specifies the raw arguments to the function, as a JSON value.
60   virtual void SetArgs(const ListValue* args) = 0;
61 
62   // Retrieves the results of the function as a JSON-encoded string (may
63   // be empty).
64   virtual const std::string GetResult() = 0;
65 
66   // Retrieves any error string from the function.
67   virtual const std::string GetError() = 0;
68 
69   // Returns a quota limit heuristic suitable for this function.
70   // No quota limiting by default.
GetQuotaLimitHeuristics(std::list<QuotaLimitHeuristic * > * heuristics)71   virtual void GetQuotaLimitHeuristics(
72       std::list<QuotaLimitHeuristic*>* heuristics) const {}
73 
set_dispatcher_peer(ExtensionFunctionDispatcher::Peer * peer)74   void set_dispatcher_peer(ExtensionFunctionDispatcher::Peer* peer) {
75     peer_ = peer;
76   }
dispatcher()77   ExtensionFunctionDispatcher* dispatcher() const {
78     return peer_->dispatcher_;
79   }
80 
set_request_id(int request_id)81   void set_request_id(int request_id) { request_id_ = request_id; }
request_id()82   int request_id() { return request_id_; }
83 
set_source_url(const GURL & source_url)84   void set_source_url(const GURL& source_url) { source_url_ = source_url; }
source_url()85   const GURL& source_url() { return source_url_; }
86 
set_has_callback(bool has_callback)87   void set_has_callback(bool has_callback) { has_callback_ = has_callback; }
has_callback()88   bool has_callback() { return has_callback_; }
89 
set_include_incognito(bool include)90   void set_include_incognito(bool include) { include_incognito_ = include; }
include_incognito()91   bool include_incognito() { return include_incognito_; }
92 
set_user_gesture(bool user_gesture)93   void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; }
user_gesture()94   bool user_gesture() const { return user_gesture_; }
95 
96   // Execute the API. Clients should call set_raw_args() and
97   // set_request_id() before calling this method. Derived classes should be
98   // ready to return raw_result() and error() before returning from this
99   // function.
100   virtual void Run() = 0;
101 
102  protected:
103   friend class base::RefCountedThreadSafe<ExtensionFunction>;
104 
105   virtual ~ExtensionFunction();
106 
107   // Gets the extension that called this function. This can return NULL for
108   // async functions, for example if the extension is unloaded while the
109   // function is running.
110   const Extension* GetExtension();
111 
112   // Gets the "current" browser, if any.
113   //
114   // Many extension APIs operate relative to the current browser, which is the
115   // browser the calling code is running inside of. For example, popups, tabs,
116   // and infobars all have a containing browser, but background pages and
117   // notification bubbles do not.
118   //
119   // If there is no containing window, the current browser defaults to the
120   // foremost one.
121   //
122   // Incognito browsers are not considered unless the calling extension has
123   // incognito access enabled.
124   //
125   // This method can return NULL if there is no matching browser, which can
126   // happen if only incognito windows are open, or early in startup or shutdown
127   // shutdown when there are no active windows.
128   Browser* GetCurrentBrowser();
129 
130   // The peer to the dispatcher that will service this extension function call.
131   scoped_refptr<ExtensionFunctionDispatcher::Peer> peer_;
132 
133   // Id of this request, used to map the response back to the caller.
134   int request_id_;
135 
136   // The Profile of this function's extension.
137   Profile* profile_;
138 
139   // The id of this function's extension.
140   std::string extension_id_;
141 
142   // The name of this function.
143   std::string name_;
144 
145   // The URL of the frame which is making this request
146   GURL source_url_;
147 
148   // True if the js caller provides a callback function to receive the response
149   // of this call.
150   bool has_callback_;
151 
152   // True if this callback should include information from incognito contexts
153   // even if our profile_ is non-incognito. Note that in the case of a "split"
154   // mode extension, this will always be false, and we will limit access to
155   // data from within the same profile_ (either incognito or not).
156   bool include_incognito_;
157 
158   // True if the call was made in response of user gesture.
159   bool user_gesture_;
160 
161   DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
162 };
163 
164 // Base class for an extension function that runs asynchronously *relative to
165 // the browser's UI thread*.
166 // Note that once Run() returns, dispatcher() can be NULL, so be sure to
167 // NULL-check.
168 // TODO(aa) Remove this extra level of inheritance once the browser stops
169 // parsing JSON (and instead uses custom serialization of Value objects).
170 class AsyncExtensionFunction : public ExtensionFunction {
171  public:
172   AsyncExtensionFunction();
173 
174   virtual void SetArgs(const ListValue* args);
175   virtual const std::string GetResult();
176   virtual const std::string GetError();
177   virtual void Run();
178 
179   // Derived classes should implement this method to do their work and return
180   // success/failure.
181   virtual bool RunImpl() = 0;
182 
183  protected:
184   virtual ~AsyncExtensionFunction();
185 
186   void SendResponse(bool success);
187 
188   // Return true if the argument to this function at |index| was provided and
189   // is non-null.
190   bool HasOptionalArgument(size_t index);
191 
192   // The arguments to the API. Only non-null if argument were specified.
193   scoped_ptr<ListValue> args_;
194 
195   // The result of the API. This should be populated by the derived class before
196   // SendResponse() is called.
197   scoped_ptr<Value> result_;
198 
199   // Any detailed error from the API. This should be populated by the derived
200   // class before Run() returns.
201   std::string error_;
202 
203   // Any class that gets a malformed message should set this to true before
204   // returning.  The calling renderer process will be killed.
205   bool bad_message_;
206 
207   DISALLOW_COPY_AND_ASSIGN(AsyncExtensionFunction);
208 };
209 
210 // A SyncExtensionFunction is an ExtensionFunction that runs synchronously
211 // *relative to the browser's UI thread*. Note that this has nothing to do with
212 // running synchronously relative to the extension process. From the extension
213 // process's point of view, the function is still asynchronous.
214 //
215 // This kind of function is convenient for implementing simple APIs that just
216 // need to interact with things on the browser UI thread.
217 class SyncExtensionFunction : public AsyncExtensionFunction {
218  public:
219   SyncExtensionFunction();
220 
221   // Derived classes should implement this method to do their work and return
222   // success/failure.
223   virtual bool RunImpl() = 0;
224 
225   virtual void Run();
226 
227  protected:
228   virtual ~SyncExtensionFunction();
229 
230  private:
231   DISALLOW_COPY_AND_ASSIGN(SyncExtensionFunction);
232 };
233 
234 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_
235