Home | History | Annotate | Download | only in browser
      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.
    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.
    157   void set_name(const std::string& name) { name_ = name; }
    158   const std::string& name() const { return name_; }
    159 
    160   void set_profile_id(void* profile_id) { profile_id_ = profile_id; }
    161   void* profile_id() const { return profile_id_; }
    162 
    163   void set_extension(const extensions::Extension* extension) {
    164     extension_ = extension;
    165   }
    166   const extensions::Extension* GetExtension() const { return extension_.get(); }
    167   const std::string& extension_id() const { return extension_->id(); }
    168 
    169   void set_request_id(int request_id) { request_id_ = request_id; }
    170   int request_id() { return request_id_; }
    171 
    172   void set_source_url(const GURL& source_url) { source_url_ = source_url; }
    173   const GURL& source_url() { return source_url_; }
    174 
    175   void set_has_callback(bool has_callback) { has_callback_ = has_callback; }
    176   bool has_callback() { return has_callback_; }
    177 
    178   void set_include_incognito(bool include) { include_incognito_ = include; }
    179   bool include_incognito() const { return include_incognito_; }
    180 
    181   void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; }
    182   bool user_gesture() const { return user_gesture_; }
    183 
    184   void set_histogram_value(
    185       extensions::functions::HistogramValue histogram_value) {
    186     histogram_value_ = histogram_value; }
    187   extensions::functions::HistogramValue histogram_value() const {
    188     return histogram_value_; }
    189 
    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 
    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.
    297   void set_context(content::BrowserContext* context) { context_ = context; }
    298   content::BrowserContext* context() const { return context_; }
    299 
    300   void SetRenderViewHost(content::RenderViewHost* render_view_host);
    301   content::RenderViewHost* render_view_host() const {
    302     return render_view_host_;
    303   }
    304 
    305   void set_dispatcher(
    306       const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher) {
    307     dispatcher_ = dispatcher;
    308   }
    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