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