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