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