| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_ |
| #define CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_ |
| #pragma once |
| |
| #include <string> |
| #include <list> |
| |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| |
| class ExtensionFunctionDispatcher; |
| class ListValue; |
| class Profile; |
| class QuotaLimitHeuristic; |
| class Value; |
| |
| #define EXTENSION_FUNCTION_VALIDATE(test) do { \ |
| if (!(test)) { \ |
| bad_message_ = true; \ |
| return false; \ |
| } \ |
| } while (0) |
| |
| #define EXTENSION_FUNCTION_ERROR(error) do { \ |
| error_ = error; \ |
| bad_message_ = true; \ |
| return false; \ |
| } while (0) |
| |
| #define DECLARE_EXTENSION_FUNCTION_NAME(name) \ |
| public: static const char* function_name() { return name; } |
| |
| // Abstract base class for extension functions the ExtensionFunctionDispatcher |
| // knows how to dispatch to. |
| class ExtensionFunction : public base::RefCountedThreadSafe<ExtensionFunction> { |
| public: |
| ExtensionFunction(); |
| |
| // Specifies the name of the function. |
| void set_name(const std::string& name) { name_ = name; } |
| const std::string name() const { return name_; } |
| |
| // Set the profile which contains the extension that has originated this |
| // function call. |
| void set_profile(Profile* profile) { profile_ = profile; } |
| Profile* profile() const { return profile_; } |
| |
| // Set the id of this function call's extension. |
| void set_extension_id(std::string extension_id) { |
| extension_id_ = extension_id; |
| } |
| std::string extension_id() const { return extension_id_; } |
| |
| // Specifies the raw arguments to the function, as a JSON value. |
| virtual void SetArgs(const ListValue* args) = 0; |
| |
| // Retrieves the results of the function as a JSON-encoded string (may |
| // be empty). |
| virtual const std::string GetResult() = 0; |
| |
| // Retrieves any error string from the function. |
| virtual const std::string GetError() = 0; |
| |
| // Returns a quota limit heuristic suitable for this function. |
| // No quota limiting by default. |
| virtual void GetQuotaLimitHeuristics( |
| std::list<QuotaLimitHeuristic*>* heuristics) const {} |
| |
| void set_dispatcher_peer(ExtensionFunctionDispatcher::Peer* peer) { |
| peer_ = peer; |
| } |
| ExtensionFunctionDispatcher* dispatcher() const { |
| return peer_->dispatcher_; |
| } |
| |
| void set_request_id(int request_id) { request_id_ = request_id; } |
| int request_id() { return request_id_; } |
| |
| void set_source_url(const GURL& source_url) { source_url_ = source_url; } |
| const GURL& source_url() { return source_url_; } |
| |
| void set_has_callback(bool has_callback) { has_callback_ = has_callback; } |
| bool has_callback() { return has_callback_; } |
| |
| void set_include_incognito(bool include) { include_incognito_ = include; } |
| bool include_incognito() { return include_incognito_; } |
| |
| void set_user_gesture(bool user_gesture) { user_gesture_ = user_gesture; } |
| bool user_gesture() const { return user_gesture_; } |
| |
| // Execute the API. Clients should call set_raw_args() and |
| // set_request_id() before calling this method. Derived classes should be |
| // ready to return raw_result() and error() before returning from this |
| // function. |
| virtual void Run() = 0; |
| |
| protected: |
| friend class base::RefCountedThreadSafe<ExtensionFunction>; |
| |
| virtual ~ExtensionFunction(); |
| |
| // Gets the extension that called this function. This can return NULL for |
| // async functions, for example if the extension is unloaded while the |
| // function is running. |
| const Extension* GetExtension(); |
| |
| // Gets the "current" browser, if any. |
| // |
| // Many extension APIs operate relative to the current browser, which is the |
| // browser the calling code is running inside of. For example, popups, tabs, |
| // and infobars all have a containing browser, but background pages and |
| // notification bubbles do not. |
| // |
| // If there is no containing window, the current browser defaults to the |
| // foremost one. |
| // |
| // Incognito browsers are not considered unless the calling extension has |
| // incognito access enabled. |
| // |
| // This method can return NULL if there is no matching browser, which can |
| // happen if only incognito windows are open, or early in startup or shutdown |
| // shutdown when there are no active windows. |
| Browser* GetCurrentBrowser(); |
| |
| // The peer to the dispatcher that will service this extension function call. |
| scoped_refptr<ExtensionFunctionDispatcher::Peer> peer_; |
| |
| // Id of this request, used to map the response back to the caller. |
| int request_id_; |
| |
| // The Profile of this function's extension. |
| Profile* profile_; |
| |
| // The id of this function's extension. |
| std::string extension_id_; |
| |
| // The name of this function. |
| std::string name_; |
| |
| // The URL of the frame which is making this request |
| GURL source_url_; |
| |
| // True if the js caller provides a callback function to receive the response |
| // of this call. |
| bool has_callback_; |
| |
| // True if this callback should include information from incognito contexts |
| // even if our profile_ is non-incognito. Note that in the case of a "split" |
| // mode extension, this will always be false, and we will limit access to |
| // data from within the same profile_ (either incognito or not). |
| bool include_incognito_; |
| |
| // True if the call was made in response of user gesture. |
| bool user_gesture_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ExtensionFunction); |
| }; |
| |
| // Base class for an extension function that runs asynchronously *relative to |
| // the browser's UI thread*. |
| // Note that once Run() returns, dispatcher() can be NULL, so be sure to |
| // NULL-check. |
| // TODO(aa) Remove this extra level of inheritance once the browser stops |
| // parsing JSON (and instead uses custom serialization of Value objects). |
| class AsyncExtensionFunction : public ExtensionFunction { |
| public: |
| AsyncExtensionFunction(); |
| |
| virtual void SetArgs(const ListValue* args); |
| virtual const std::string GetResult(); |
| virtual const std::string GetError(); |
| virtual void Run(); |
| |
| // Derived classes should implement this method to do their work and return |
| // success/failure. |
| virtual bool RunImpl() = 0; |
| |
| protected: |
| virtual ~AsyncExtensionFunction(); |
| |
| void SendResponse(bool success); |
| |
| // Return true if the argument to this function at |index| was provided and |
| // is non-null. |
| bool HasOptionalArgument(size_t index); |
| |
| // The arguments to the API. Only non-null if argument were specified. |
| scoped_ptr<ListValue> args_; |
| |
| // The result of the API. This should be populated by the derived class before |
| // SendResponse() is called. |
| scoped_ptr<Value> result_; |
| |
| // Any detailed error from the API. This should be populated by the derived |
| // class before Run() returns. |
| std::string error_; |
| |
| // Any class that gets a malformed message should set this to true before |
| // returning. The calling renderer process will be killed. |
| bool bad_message_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AsyncExtensionFunction); |
| }; |
| |
| // A SyncExtensionFunction is an ExtensionFunction that runs synchronously |
| // *relative to the browser's UI thread*. Note that this has nothing to do with |
| // running synchronously relative to the extension process. From the extension |
| // process's point of view, the function is still asynchronous. |
| // |
| // This kind of function is convenient for implementing simple APIs that just |
| // need to interact with things on the browser UI thread. |
| class SyncExtensionFunction : public AsyncExtensionFunction { |
| public: |
| SyncExtensionFunction(); |
| |
| // Derived classes should implement this method to do their work and return |
| // success/failure. |
| virtual bool RunImpl() = 0; |
| |
| virtual void Run(); |
| |
| protected: |
| virtual ~SyncExtensionFunction(); |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(SyncExtensionFunction); |
| }; |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FUNCTION_H_ |