• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 EXTENSIONS_BROWSER_EXTENSION_FUNCTION_H_
6 #define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_H_
7 
8 #include <list>
9 #include <string>
10 
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/process/process.h"
17 #include "base/sequenced_task_runner_helpers.h"
18 #include "chrome/browser/extensions/extension_function_histogram_value.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/common/console_message_level.h"
21 #include "extensions/browser/info_map.h"
22 #include "extensions/common/extension.h"
23 #include "ipc/ipc_message.h"
24 
25 class ChromeRenderMessageFilter;
26 class ExtensionFunction;
27 class ExtensionFunctionDispatcher;
28 class UIThreadExtensionFunction;
29 class IOThreadExtensionFunction;
30 
31 namespace base {
32 class ListValue;
33 class Value;
34 }
35 
36 namespace content {
37 class BrowserContext;
38 class RenderViewHost;
39 class WebContents;
40 }
41 
42 namespace extensions {
43 class QuotaLimitHeuristic;
44 }
45 
46 #ifdef NDEBUG
47 #define EXTENSION_FUNCTION_VALIDATE(test) do { \
48     if (!(test)) { \
49       bad_message_ = true; \
50       return false; \
51     } \
52   } while (0)
53 #else   // NDEBUG
54 #define EXTENSION_FUNCTION_VALIDATE(test) CHECK(test)
55 #endif  // NDEBUG
56 
57 #define EXTENSION_FUNCTION_ERROR(error) do { \
58     error_ = error; \
59     bad_message_ = true; \
60     return false; \
61   } while (0)
62 
63 // Declares a callable extension function with the given |name|. You must also
64 // supply a unique |histogramvalue| used for histograms of extension function
65 // invocation (add new ones at the end of the enum in
66 // extension_function_histogram_value.h).
67 #define DECLARE_EXTENSION_FUNCTION(name, histogramvalue) \
68   public: static const char* function_name() { return name; } \
69   public: static extensions::functions::HistogramValue histogram_value() \
70     { return extensions::functions::histogramvalue; }
71 
72 // Traits that describe how ExtensionFunction should be deleted. This just calls
73 // the virtual "Destruct" method on ExtensionFunction, allowing derived classes
74 // to override the behavior.
75 struct ExtensionFunctionDeleteTraits {
76  public:
77   static void Destruct(const ExtensionFunction* x);
78 };
79 
80 // Abstract base class for extension functions the ExtensionFunctionDispatcher
81 // knows how to dispatch to.
82 class ExtensionFunction
83     : public base::RefCountedThreadSafe<ExtensionFunction,
84                                         ExtensionFunctionDeleteTraits> {
85  public:
86   enum ResponseType {
87     // The function has succeeded.
88     SUCCEEDED,
89     // The function has failed.
90     FAILED,
91     // The input message is malformed.
92     BAD_MESSAGE
93   };
94 
95   typedef base::Callback<void(ResponseType type,
96                               const base::ListValue& results,
97                               const std::string& error)> ResponseCallback;
98 
99   ExtensionFunction();
100 
101   virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction();
102   virtual IOThreadExtensionFunction* AsIOThreadExtensionFunction();
103 
104   // Returns true if the function has permission to run.
105   //
106   // The default implementation is to check the Extension's permissions against
107   // what this function requires to run, but some APIs may require finer
108   // grained control, such as tabs.executeScript being allowed for active tabs.
109   //
110   // This will be run after the function has been set up but before Run().
111   virtual bool HasPermission();
112 
113   // Execute the API. Clients should initialize the ExtensionFunction using
114   // SetArgs(), set_request_id(), and the other setters before calling this
115   // method. Derived classes should be ready to return GetResultList() and
116   // GetError() before returning from this function.
117   // Note that once Run() returns, dispatcher() can be NULL, so be sure to
118   // NULL-check.
119   virtual void Run();
120 
121   // Gets whether quota should be applied to this individual function
122   // invocation. This is different to GetQuotaLimitHeuristics which is only
123   // invoked once and then cached.
124   //
125   // Returns false by default.
126   virtual bool ShouldSkipQuotaLimiting() const;
127 
128   // Optionally adds one or multiple QuotaLimitHeuristic instances suitable for
129   // this function to |heuristics|. The ownership of the new QuotaLimitHeuristic
130   // instances is passed to the owner of |heuristics|.
131   // No quota limiting by default.
132   //
133   // Only called once per lifetime of the QuotaService.
GetQuotaLimitHeuristics(extensions::QuotaLimitHeuristics * heuristics)134   virtual void GetQuotaLimitHeuristics(
135       extensions::QuotaLimitHeuristics* heuristics) const {}
136 
137   // Called when the quota limit has been exceeded. The default implementation
138   // returns an error.
139   virtual void OnQuotaExceeded(const std::string& violation_error);
140 
141   // Specifies the raw arguments to the function, as a JSON value.
142   virtual void SetArgs(const base::ListValue* args);
143 
144   // Sets a single Value as the results of the function.
145   void SetResult(base::Value* result);
146 
147   // Retrieves the results of the function as a ListValue.
148   const base::ListValue* GetResultList();
149 
150   // Retrieves any error string from the function.
151   virtual const std::string GetError();
152 
153   // Sets the function's error string.
154   virtual void SetError(const std::string& error);
155 
156   // Specifies the name of the function.
set_name(const std::string & name)157   void set_name(const std::string& name) { name_ = name; }
name()158   const std::string& name() const { return name_; }
159 
set_profile_id(void * profile_id)160   void set_profile_id(void* profile_id) { profile_id_ = profile_id; }
profile_id()161   void* profile_id() const { return profile_id_; }
162 
set_extension(const extensions::Extension * extension)163   void set_extension(const extensions::Extension* extension) {
164     extension_ = extension;
165   }
GetExtension()166   const extensions::Extension* GetExtension() const { return extension_.get(); }
extension_id()167   const std::string& extension_id() const { return extension_->id(); }
168 
set_request_id(int request_id)169   void set_request_id(int request_id) { request_id_ = request_id; }
request_id()170   int request_id() { return request_id_; }
171 
set_source_url(const GURL & source_url)172   void set_source_url(const GURL& source_url) { source_url_ = source_url; }
source_url()173   const GURL& source_url() { return source_url_; }
174 
set_has_callback(bool has_callback)175   void set_has_callback(bool has_callback) { has_callback_ = has_callback; }
has_callback()176   bool has_callback() { return has_callback_; }
177 
set_include_incognito(bool include)178   void set_include_incognito(bool include) { include_incognito_ = include; }
include_incognito()179   bool include_incognito() const { return include_incognito_; }
180 
set_user_gesture(bool user_gesture)181   void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; }
user_gesture()182   bool user_gesture() const { return user_gesture_; }
183 
set_histogram_value(extensions::functions::HistogramValue histogram_value)184   void set_histogram_value(
185       extensions::functions::HistogramValue histogram_value) {
186     histogram_value_ = histogram_value; }
histogram_value()187   extensions::functions::HistogramValue histogram_value() const {
188     return histogram_value_; }
189 
set_response_callback(const ResponseCallback & callback)190   void set_response_callback(const ResponseCallback& callback) {
191     response_callback_ = callback;
192   }
193 
194  protected:
195   friend struct ExtensionFunctionDeleteTraits;
196 
197   virtual ~ExtensionFunction();
198 
199   // Helper method for ExtensionFunctionDeleteTraits. Deletes this object.
200   virtual void Destruct() const = 0;
201 
202   // Derived classes should implement this method to do their work and return
203   // success/failure.
204   virtual bool RunImpl() = 0;
205 
206   // Sends the result back to the extension.
207   virtual void SendResponse(bool success) = 0;
208 
209   // Common implementation for SendResponse.
210   void SendResponseImpl(bool success);
211 
212   // Return true if the argument to this function at |index| was provided and
213   // is non-null.
214   bool HasOptionalArgument(size_t index);
215 
216   // Id of this request, used to map the response back to the caller.
217   int request_id_;
218 
219   // The id of the profile of this function's extension.
220   void* profile_id_;
221 
222   // The extension that called this function.
223   scoped_refptr<const extensions::Extension> extension_;
224 
225   // The name of this function.
226   std::string name_;
227 
228   // The URL of the frame which is making this request
229   GURL source_url_;
230 
231   // True if the js caller provides a callback function to receive the response
232   // of this call.
233   bool has_callback_;
234 
235   // True if this callback should include information from incognito contexts
236   // even if our profile_ is non-incognito. Note that in the case of a "split"
237   // mode extension, this will always be false, and we will limit access to
238   // data from within the same profile_ (either incognito or not).
239   bool include_incognito_;
240 
241   // True if the call was made in response of user gesture.
242   bool user_gesture_;
243 
244   // The arguments to the API. Only non-null if argument were specified.
245   scoped_ptr<base::ListValue> args_;
246 
247   // The results of the API. This should be populated by the derived class
248   // before SendResponse() is called.
249   scoped_ptr<base::ListValue> results_;
250 
251   // Any detailed error from the API. This should be populated by the derived
252   // class before Run() returns.
253   std::string error_;
254 
255   // Any class that gets a malformed message should set this to true before
256   // returning.  Usually we want to kill the message sending process.
257   bool bad_message_;
258 
259   // The sample value to record with the histogram API when the function
260   // is invoked.
261   extensions::functions::HistogramValue histogram_value_;
262 
263   // The callback to run once the function has done execution.
264   ResponseCallback response_callback_;
265 
266   DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
267 };
268 
269 // Extension functions that run on the UI thread. Most functions fall into
270 // this category.
271 class UIThreadExtensionFunction : public ExtensionFunction {
272  public:
273   // TODO(yzshen): We should be able to remove this interface now that we
274   // support overriding the response callback.
275   // A delegate for use in testing, to intercept the call to SendResponse.
276   class DelegateForTests {
277    public:
278     virtual void OnSendResponse(UIThreadExtensionFunction* function,
279                                 bool success,
280                                 bool bad_message) = 0;
281   };
282 
283   UIThreadExtensionFunction();
284 
285   virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() OVERRIDE;
286 
set_test_delegate(DelegateForTests * delegate)287   void set_test_delegate(DelegateForTests* delegate) {
288     delegate_ = delegate;
289   }
290 
291   // Called when a message was received.
292   // Should return true if it processed the message.
293   virtual bool OnMessageReceivedFromRenderView(const IPC::Message& message);
294 
295   // Set the browser context which contains the extension that has originated
296   // this function call.
set_context(content::BrowserContext * context)297   void set_context(content::BrowserContext* context) { context_ = context; }
context()298   content::BrowserContext* context() const { return context_; }
299 
300   void SetRenderViewHost(content::RenderViewHost* render_view_host);
render_view_host()301   content::RenderViewHost* render_view_host() const {
302     return render_view_host_;
303   }
304 
set_dispatcher(const base::WeakPtr<ExtensionFunctionDispatcher> & dispatcher)305   void set_dispatcher(
306       const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher) {
307     dispatcher_ = dispatcher;
308   }
dispatcher()309   ExtensionFunctionDispatcher* dispatcher() const {
310     return dispatcher_.get();
311   }
312 
313   // Gets the "current" web contents if any. If there is no associated web
314   // contents then defaults to the foremost one.
315   virtual content::WebContents* GetAssociatedWebContents();
316 
317  protected:
318   // Emits a message to the extension's devtools console.
319   void WriteToConsole(content::ConsoleMessageLevel level,
320                       const std::string& message);
321 
322   friend struct content::BrowserThread::DeleteOnThread<
323       content::BrowserThread::UI>;
324   friend class base::DeleteHelper<UIThreadExtensionFunction>;
325 
326   virtual ~UIThreadExtensionFunction();
327 
328   virtual void SendResponse(bool success) OVERRIDE;
329 
330   // The dispatcher that will service this extension function call.
331   base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_;
332 
333   // The RenderViewHost we will send responses too.
334   content::RenderViewHost* render_view_host_;
335 
336   // The content::BrowserContext of this function's extension.
337   content::BrowserContext* context_;
338 
339  private:
340   class RenderViewHostTracker;
341 
342   virtual void Destruct() const OVERRIDE;
343 
344   scoped_ptr<RenderViewHostTracker> tracker_;
345 
346   DelegateForTests* delegate_;
347 };
348 
349 // Extension functions that run on the IO thread. This type of function avoids
350 // a roundtrip to and from the UI thread (because communication with the
351 // extension process happens on the IO thread). It's intended to be used when
352 // performance is critical (e.g. the webRequest API which can block network
353 // requests). Generally, UIThreadExtensionFunction is more appropriate and will
354 // be easier to use and interface with the rest of the browser.
355 class IOThreadExtensionFunction : public ExtensionFunction {
356  public:
357   IOThreadExtensionFunction();
358 
359   virtual IOThreadExtensionFunction* AsIOThreadExtensionFunction() OVERRIDE;
360 
361   void set_ipc_sender(base::WeakPtr<ChromeRenderMessageFilter> ipc_sender,
362                       int routing_id) {
363     ipc_sender_ = ipc_sender;
364     routing_id_ = routing_id;
365   }
366 
367   base::WeakPtr<ChromeRenderMessageFilter> ipc_sender_weak() const {
368     return ipc_sender_;
369   }
370 
371   int routing_id() const { return routing_id_; }
372 
373   void set_extension_info_map(const extensions::InfoMap* extension_info_map) {
374     extension_info_map_ = extension_info_map;
375   }
376   const extensions::InfoMap* extension_info_map() const {
377     return extension_info_map_.get();
378   }
379 
380  protected:
381   friend struct content::BrowserThread::DeleteOnThread<
382       content::BrowserThread::IO>;
383   friend class base::DeleteHelper<IOThreadExtensionFunction>;
384 
385   virtual ~IOThreadExtensionFunction();
386 
387   virtual void Destruct() const OVERRIDE;
388 
389   virtual void SendResponse(bool success) OVERRIDE;
390 
391  private:
392   base::WeakPtr<ChromeRenderMessageFilter> ipc_sender_;
393   int routing_id_;
394 
395   scoped_refptr<const extensions::InfoMap> extension_info_map_;
396 };
397 
398 // Base class for an extension function that runs asynchronously *relative to
399 // the browser's UI thread*.
400 class AsyncExtensionFunction : public UIThreadExtensionFunction {
401  public:
402   AsyncExtensionFunction();
403 
404  protected:
405   virtual ~AsyncExtensionFunction();
406 };
407 
408 // A SyncExtensionFunction is an ExtensionFunction that runs synchronously
409 // *relative to the browser's UI thread*. Note that this has nothing to do with
410 // running synchronously relative to the extension process. From the extension
411 // process's point of view, the function is still asynchronous.
412 //
413 // This kind of function is convenient for implementing simple APIs that just
414 // need to interact with things on the browser UI thread.
415 class SyncExtensionFunction : public UIThreadExtensionFunction {
416  public:
417   SyncExtensionFunction();
418 
419   virtual void Run() OVERRIDE;
420 
421  protected:
422   virtual ~SyncExtensionFunction();
423 };
424 
425 class SyncIOThreadExtensionFunction : public IOThreadExtensionFunction {
426  public:
427   SyncIOThreadExtensionFunction();
428 
429   virtual void Run() OVERRIDE;
430 
431  protected:
432   virtual ~SyncIOThreadExtensionFunction();
433 };
434 
435 #endif  // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_H_
436