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 26 class Browser; 27 class ChromeRenderMessageFilter; 28 class ExtensionFunction; 29 class ExtensionFunctionDispatcher; 30 class UIThreadExtensionFunction; 31 class IOThreadExtensionFunction; 32 class Profile; 33 class QuotaLimitHeuristic; 34 35 namespace base { 36 class ListValue; 37 class Value; 38 } 39 40 namespace content { 41 class RenderViewHost; 42 class WebContents; 43 } 44 45 namespace extensions { 46 class 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. 78 struct 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. 85 class 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. 274 class 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. 402 class 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*. 447 class 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. 462 class SyncExtensionFunction : public UIThreadExtensionFunction { 463 public: 464 SyncExtensionFunction(); 465 466 virtual void Run() OVERRIDE; 467 468 protected: 469 virtual ~SyncExtensionFunction(); 470 }; 471 472 class 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