Home | History | Annotate | Download | only in extensions
      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_RENDERER_EXTENSIONS_DISPATCHER_H_
      6 #define CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/memory/shared_memory.h"
     14 #include "base/timer/timer.h"
     15 #include "chrome/common/extensions/extension_set.h"
     16 #include "chrome/common/extensions/features/feature.h"
     17 #include "chrome/renderer/extensions/chrome_v8_context.h"
     18 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
     19 #include "chrome/renderer/extensions/v8_schema_registry.h"
     20 #include "chrome/renderer/resource_bundle_source_map.h"
     21 #include "content/public/renderer/render_process_observer.h"
     22 #include "extensions/common/event_filter.h"
     23 #include "v8/include/v8.h"
     24 
     25 class ChromeRenderViewTest;
     26 class GURL;
     27 class ModuleSystem;
     28 class URLPattern;
     29 struct ExtensionMsg_ExternalConnectionInfo;
     30 struct ExtensionMsg_Loaded_Params;
     31 
     32 namespace WebKit {
     33 class WebFrame;
     34 class WebSecurityOrigin;
     35 }
     36 
     37 namespace base {
     38 class DictionaryValue;
     39 class ListValue;
     40 }
     41 
     42 namespace content {
     43 class RenderThread;
     44 }
     45 
     46 namespace extensions {
     47 class ContentWatcher;
     48 class Extension;
     49 class FilteredEventRouter;
     50 class RequestSender;
     51 class UserScriptSlave;
     52 
     53 // Dispatches extension control messages sent to the renderer and stores
     54 // renderer extension related state.
     55 class Dispatcher : public content::RenderProcessObserver {
     56  public:
     57   Dispatcher();
     58   virtual ~Dispatcher();
     59 
     60   const std::set<std::string>& function_names() const {
     61     return function_names_;
     62   }
     63 
     64   bool is_extension_process() const { return is_extension_process_; }
     65   const ExtensionSet* extensions() const { return &extensions_; }
     66   const ChromeV8ContextSet& v8_context_set() const {
     67     return v8_context_set_;
     68   }
     69   UserScriptSlave* user_script_slave() {
     70     return user_script_slave_.get();
     71   }
     72   V8SchemaRegistry* v8_schema_registry() {
     73     return v8_schema_registry_.get();
     74   }
     75   ContentWatcher* content_watcher() {
     76     return content_watcher_.get();
     77   }
     78   RequestSender* request_sender() {
     79     return request_sender_.get();
     80   }
     81 
     82   bool IsExtensionActive(const std::string& extension_id) const;
     83 
     84   // Finds the extension ID for the JavaScript context associated with the
     85   // specified |frame| and isolated world. If |world_id| is zero, finds the
     86   // extension ID associated with the main world's JavaScript context. If the
     87   // JavaScript context isn't from an extension, returns empty string.
     88   std::string GetExtensionID(const WebKit::WebFrame* frame, int world_id);
     89 
     90   void DidCreateScriptContext(WebKit::WebFrame* frame,
     91                               v8::Handle<v8::Context> context,
     92                               int extension_group,
     93                               int world_id);
     94   void WillReleaseScriptContext(WebKit::WebFrame* frame,
     95                                 v8::Handle<v8::Context> context,
     96                                 int world_id);
     97 
     98   void DidCreateDocumentElement(WebKit::WebFrame* frame);
     99 
    100   // TODO(mpcomplete): remove. http://crbug.com/100411
    101   bool IsAdblockWithWebRequestInstalled() const {
    102     return webrequest_adblock_;
    103   }
    104   bool IsAdblockPlusWithWebRequestInstalled() const {
    105     return webrequest_adblock_plus_;
    106   }
    107   bool IsOtherExtensionWithWebRequestInstalled() const {
    108     return webrequest_other_;
    109   }
    110 
    111   void OnExtensionResponse(int request_id,
    112                            bool success,
    113                            const base::ListValue& response,
    114                            const std::string& error);
    115 
    116   // Checks that the current context contains an extension that has permission
    117   // to execute the specified function. If it does not, a v8 exception is thrown
    118   // and the method returns false. Otherwise returns true.
    119   bool CheckContextAccessToExtensionAPI(
    120       const std::string& function_name, ChromeV8Context* context) const;
    121 
    122   // Dispatches the event named |event_name| to all render views.
    123   void DispatchEvent(const std::string& extension_id,
    124                      const std::string& event_name) const;
    125 
    126   // Shared implementation of the various MessageInvoke IPCs.
    127   void InvokeModuleSystemMethod(
    128       content::RenderView* render_view,
    129       const std::string& extension_id,
    130       const std::string& module_name,
    131       const std::string& function_name,
    132       const base::ListValue& args,
    133       bool user_gesture);
    134 
    135  private:
    136   friend class ::ChromeRenderViewTest;
    137   FRIEND_TEST_ALL_PREFIXES(RendererPermissionsPolicyDelegateTest,
    138                            CannotScriptWebstore);
    139   typedef void (*BindingInstaller)(ModuleSystem* module_system,
    140                                   v8::Handle<v8::Object> chrome);
    141 
    142   // RenderProcessObserver implementation:
    143   virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
    144   virtual void WebKitInitialized() OVERRIDE;
    145   virtual void IdleNotification() OVERRIDE;
    146   virtual void OnRenderProcessShutdown() OVERRIDE;
    147 
    148   void OnSetChannel(int channel);
    149   void OnMessageInvoke(const std::string& extension_id,
    150                        const std::string& module_name,
    151                        const std::string& function_name,
    152                        const base::ListValue& args,
    153                        bool user_gesture);
    154   void OnDispatchOnConnect(int target_port_id,
    155                            const std::string& channel_name,
    156                            const base::DictionaryValue& source_tab,
    157                            const ExtensionMsg_ExternalConnectionInfo& info);
    158   void OnDeliverMessage(int target_port_id, const std::string& message);
    159   void OnDispatchOnDisconnect(int port_id, const std::string& error_message);
    160   void OnSetFunctionNames(const std::vector<std::string>& names);
    161   void OnSetSystemFont(const std::string& font_family,
    162                        const std::string& font_size);
    163   void OnLoaded(
    164       const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions);
    165   void OnLoadedInternal(scoped_refptr<const Extension> extension);
    166   void OnUnloaded(const std::string& id);
    167   void OnSetScriptingWhitelist(
    168       const Extension::ScriptingWhitelist& extension_ids);
    169   void OnPageActionsUpdated(const std::string& extension_id,
    170       const std::vector<std::string>& page_actions);
    171   void OnActivateExtension(const std::string& extension_id);
    172   void OnUpdatePermissions(int reason_id,
    173                            const std::string& extension_id,
    174                            const APIPermissionSet& apis,
    175                            const URLPatternSet& explicit_hosts,
    176                            const URLPatternSet& scriptable_hosts);
    177   void OnUpdateTabSpecificPermissions(int page_id,
    178                                       int tab_id,
    179                                       const std::string& extension_id,
    180                                       const URLPatternSet& origin_set);
    181   void OnClearTabSpecificPermissions(
    182       int tab_id,
    183       const std::vector<std::string>& extension_ids);
    184   void OnUpdateUserScripts(base::SharedMemoryHandle table);
    185   void OnUsingWebRequestAPI(
    186       bool adblock,
    187       bool adblock_plus,
    188       bool other_webrequest);
    189   void OnShouldSuspend(const std::string& extension_id, int sequence_id);
    190   void OnSuspend(const std::string& extension_id);
    191   void OnCancelSuspend(const std::string& extension_id);
    192 
    193   // Update the list of active extensions that will be reported when we crash.
    194   void UpdateActiveExtensions();
    195 
    196   // Sets up the host permissions for |extension|.
    197   void InitOriginPermissions(const Extension* extension);
    198   void AddOrRemoveOriginPermissions(
    199       UpdatedExtensionPermissionsInfo::Reason reason,
    200       const Extension* extension,
    201       const URLPatternSet& origins);
    202 
    203   // Enable custom element whitelist in Apps.
    204   void EnableCustomElementWhiteList();
    205 
    206   // Adds or removes bindings for every context belonging to |extension_id|, or
    207   // or all contexts if |extension_id| is empty.
    208   void AddOrRemoveBindings(const std::string& extension_id);
    209 
    210   void RegisterNativeHandlers(ModuleSystem* module_system,
    211                               ChromeV8Context* context);
    212   void AddOrRemoveBindingsForContext(ChromeV8Context* context);
    213   void RegisterBinding(const std::string& api_name,
    214                        ChromeV8Context* context);
    215   void DeregisterBinding(const std::string& api_name, ChromeV8Context* context);
    216   v8::Handle<v8::Object> GetOrCreateBindObjectIfAvailable(
    217       const std::string& api_name,
    218       std::string* bind_name,
    219       ChromeV8Context* context);
    220 
    221   // Inserts static source code into |source_map_|.
    222   void PopulateSourceMap();
    223 
    224   // Inserts BindingInstallers into |lazy_bindings_map_|.
    225   void PopulateLazyBindingsMap();
    226 
    227   // Sets up the bindings for the given api.
    228   void InstallBindings(ModuleSystem* module_system,
    229                        v8::Handle<v8::Context> v8_context,
    230                        const std::string& api);
    231 
    232   // Returns whether the current renderer hosts a platform app.
    233   bool IsWithinPlatformApp();
    234 
    235   bool IsSandboxedPage(const GURL& url) const;
    236 
    237   // Returns the Feature::Context type of context for a JavaScript context.
    238   Feature::Context ClassifyJavaScriptContext(
    239       const std::string& extension_id,
    240       int extension_group,
    241       const GURL& url,
    242       const WebKit::WebSecurityOrigin& origin);
    243 
    244   // Gets |field| from |object| or creates it as an empty object if it doesn't
    245   // exist.
    246   v8::Handle<v8::Object> GetOrCreateObject(v8::Handle<v8::Object> object,
    247                                            const std::string& field);
    248 
    249   // True if this renderer is running extensions.
    250   bool is_extension_process_;
    251 
    252   // Contains all loaded extensions.  This is essentially the renderer
    253   // counterpart to ExtensionService in the browser. It contains information
    254   // about all extensions currently loaded by the browser.
    255   ExtensionSet extensions_;
    256 
    257   // The IDs of extensions that failed to load, mapped to the error message
    258   // generated on failure.
    259   std::map<std::string, std::string> extension_load_errors_;
    260 
    261   // All the bindings contexts that are currently loaded for this renderer.
    262   // There is zero or one for each v8 context.
    263   ChromeV8ContextSet v8_context_set_;
    264 
    265   scoped_ptr<UserScriptSlave> user_script_slave_;
    266 
    267   scoped_ptr<ContentWatcher> content_watcher_;
    268 
    269   // Same as above, but on a longer timer and will run even if the process is
    270   // not idle, to ensure that IdleHandle gets called eventually.
    271   base::RepeatingTimer<content::RenderThread> forced_idle_timer_;
    272 
    273   // All declared function names.
    274   std::set<std::string> function_names_;
    275 
    276   // The extensions and apps that are active in this process.
    277   std::set<std::string> active_extension_ids_;
    278 
    279   // True once WebKit has been initialized (and it is therefore safe to poke).
    280   bool is_webkit_initialized_;
    281 
    282   // Status of webrequest usage for known extensions.
    283   // TODO(mpcomplete): remove. http://crbug.com/100411
    284   bool webrequest_adblock_;
    285   bool webrequest_adblock_plus_;
    286   bool webrequest_other_;
    287 
    288   ResourceBundleSourceMap source_map_;
    289 
    290   // Cache for the v8 representation of extension API schemas.
    291   scoped_ptr<V8SchemaRegistry> v8_schema_registry_;
    292 
    293   // Bindings that are defined lazily and have BindingInstallers to install
    294   // them.
    295   std::map<std::string, BindingInstaller> lazy_bindings_map_;
    296 
    297   // Sends API requests to the extension host.
    298   scoped_ptr<RequestSender> request_sender_;
    299 
    300   // The platforms system font family and size;
    301   std::string system_font_family_;
    302   std::string system_font_size_;
    303 
    304   DISALLOW_COPY_AND_ASSIGN(Dispatcher);
    305 };
    306 
    307 }  // namespace extensions
    308 
    309 #endif  // CHROME_RENDERER_EXTENSIONS_DISPATCHER_H_
    310