summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-26 22:48:12 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-26 22:48:12 +0000
commita2aef2ea9d7d923a9c1c768eadd1092ce46b64bf (patch)
tree5f78f3f4cf0ea1d08ee4eafa0e22118d8486440f /chrome/browser/extensions
parent5bd4938ab9c427e324933fa3689d2de7bfc4e315 (diff)
downloadchromium_src-a2aef2ea9d7d923a9c1c768eadd1092ce46b64bf.zip
chromium_src-a2aef2ea9d7d923a9c1c768eadd1092ce46b64bf.tar.gz
chromium_src-a2aef2ea9d7d923a9c1c768eadd1092ce46b64bf.tar.bz2
Split UI-specific bits off ExtensionFunction into a separate class.
This is a precursor to another patch I'm working on, which will add ExtensionFunctions that can run on the IO thread. The webRequest API will use this. I've also done a bit of other cleanup: - moved almost everything off of {Async,Sync}ExtensionFunction, up into the base class, since none of it was specific to either of those. - store Extension directly on ExtensionFunction, rather than needing to look it up, since it is now refcounted. BUG=no TEST=no Review URL: http://codereview.chromium.org/7073001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86919 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc1
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.cc1
-rw-r--r--chrome/browser/extensions/extension_debugger_api.h1
-rw-r--r--chrome/browser/extensions/extension_function.cc90
-rw-r--r--chrome/browser/extensions/extension_function.h273
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc16
-rw-r--r--chrome/browser/extensions/extension_test_api.cc1
-rw-r--r--chrome/browser/extensions/extension_webstore_private_api.cc1
-rw-r--r--chrome/browser/extensions/extensions_quota_service_unittest.cc4
9 files changed, 224 insertions, 164 deletions
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index 6d89d373..d3445fa 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/extensions/extension_bookmark_helpers.h"
#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
#include "chrome/browser/extensions/extension_event_router.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_web_ui.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc
index f17ab59..1358ee6 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.cc
+++ b/chrome/browser/extensions/extension_bookmarks_module.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/extensions/extension_bookmark_helpers.h"
#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
#include "chrome/browser/extensions/extension_event_router.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/importer/importer_host.h"
diff --git a/chrome/browser/extensions/extension_debugger_api.h b/chrome/browser/extensions/extension_debugger_api.h
index 5fd9d00..6d1642e 100644
--- a/chrome/browser/extensions/extension_debugger_api.h
+++ b/chrome/browser/extensions/extension_debugger_api.h
@@ -17,6 +17,7 @@
class DictionaryValue;
class ExtensionDevToolsClientHost;
+class TabContents;
class DebuggerFunction : public AsyncExtensionFunction {
protected:
diff --git a/chrome/browser/extensions/extension_function.cc b/chrome/browser/extensions/extension_function.cc
index f390d72..def3edb 100644
--- a/chrome/browser/extensions/extension_function.cc
+++ b/chrome/browser/extensions/extension_function.cc
@@ -17,15 +17,20 @@
#include "content/common/notification_type.h"
#include "content/common/result_codes.h"
-ExtensionFunction::RenderViewHostTracker::RenderViewHostTracker(
- ExtensionFunction* function)
+// static
+void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) {
+ x->Destruct();
+}
+
+UIThreadExtensionFunction::RenderViewHostTracker::RenderViewHostTracker(
+ UIThreadExtensionFunction* function)
: function_(function) {
registrar_.Add(this,
NotificationType::RENDER_VIEW_HOST_DELETED,
Source<RenderViewHost>(function->render_view_host()));
}
-void ExtensionFunction::RenderViewHostTracker::Observe(
+void UIThreadExtensionFunction::RenderViewHostTracker::Observe(
NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -37,43 +42,23 @@ void ExtensionFunction::RenderViewHostTracker::Observe(
ExtensionFunction::ExtensionFunction()
: request_id_(-1),
- profile_(NULL),
+ profile_id_(0),
has_callback_(false),
include_incognito_(false),
- user_gesture_(false) {
+ user_gesture_(false),
+ args_(NULL),
+ bad_message_(false) {
}
ExtensionFunction::~ExtensionFunction() {
}
-void ExtensionFunction::SetRenderViewHost(RenderViewHost* render_view_host) {
- render_view_host_ = render_view_host;
- tracker_.reset(render_view_host ? new RenderViewHostTracker(this) : NULL);
-}
-
-const Extension* ExtensionFunction::GetExtension() {
- ExtensionService* service = profile_->GetExtensionService();
- DCHECK(service);
- return service->GetExtensionById(extension_id_, false);
-}
-
-Browser* ExtensionFunction::GetCurrentBrowser() {
- return dispatcher()->GetCurrentBrowser(render_view_host_, include_incognito_);
-}
-
-AsyncExtensionFunction::AsyncExtensionFunction()
- : args_(NULL), bad_message_(false) {
-}
-
-AsyncExtensionFunction::~AsyncExtensionFunction() {
-}
-
-void AsyncExtensionFunction::SetArgs(const ListValue* args) {
+void ExtensionFunction::SetArgs(const ListValue* args) {
DCHECK(!args_.get()); // Should only be called once.
args_.reset(args->DeepCopy());
}
-const std::string AsyncExtensionFunction::GetResult() {
+const std::string ExtensionFunction::GetResult() {
std::string json;
// Some functions might not need to return any results.
if (result_.get())
@@ -81,16 +66,42 @@ const std::string AsyncExtensionFunction::GetResult() {
return json;
}
-const std::string AsyncExtensionFunction::GetError() {
+const std::string ExtensionFunction::GetError() {
return error_;
}
-void AsyncExtensionFunction::Run() {
+void ExtensionFunction::Run() {
if (!RunImpl())
SendResponse(false);
}
-void AsyncExtensionFunction::SendResponse(bool success) {
+bool ExtensionFunction::HasOptionalArgument(size_t index) {
+ Value* value;
+ return args_->Get(index, &value) && !value->IsType(Value::TYPE_NULL);
+}
+
+UIThreadExtensionFunction::UIThreadExtensionFunction()
+ : profile_(NULL) {
+}
+
+UIThreadExtensionFunction::~UIThreadExtensionFunction() {
+}
+
+void UIThreadExtensionFunction::Destruct() const {
+ BrowserThread::DeleteOnUIThread::Destruct(this);
+}
+
+void UIThreadExtensionFunction::SetRenderViewHost(
+ RenderViewHost* render_view_host) {
+ render_view_host_ = render_view_host;
+ tracker_.reset(render_view_host ? new RenderViewHostTracker(this) : NULL);
+}
+
+Browser* UIThreadExtensionFunction::GetCurrentBrowser() {
+ return dispatcher()->GetCurrentBrowser(render_view_host_, include_incognito_);
+}
+
+void UIThreadExtensionFunction::SendResponse(bool success) {
if (!render_view_host_ || !dispatcher())
return;
if (bad_message_) {
@@ -103,7 +114,7 @@ void AsyncExtensionFunction::SendResponse(bool success) {
GetResult(), GetError()));
}
-void AsyncExtensionFunction::HandleBadMessage() {
+void UIThreadExtensionFunction::HandleBadMessage() {
LOG(ERROR) << "bad extension message " << name_ << " : terminating renderer.";
if (RenderProcessHost::run_renderer_in_process()) {
// In single process mode it is better if we don't suicide but just crash.
@@ -111,14 +122,17 @@ void AsyncExtensionFunction::HandleBadMessage() {
} else {
NOTREACHED();
UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD"));
- base::KillProcess(render_view_host_->process()->GetHandle(),
- ResultCodes::KILLED_BAD_MESSAGE, false);
+ if (render_view_host_) {
+ base::KillProcess(render_view_host_->process()->GetHandle(),
+ ResultCodes::KILLED_BAD_MESSAGE, false);
+ }
}
}
-bool AsyncExtensionFunction::HasOptionalArgument(size_t index) {
- Value* value;
- return args_->Get(index, &value) && !value->IsType(Value::TYPE_NULL);
+AsyncExtensionFunction::AsyncExtensionFunction() {
+}
+
+AsyncExtensionFunction::~AsyncExtensionFunction() {
}
SyncExtensionFunction::SyncExtensionFunction() {
diff --git a/chrome/browser/extensions/extension_function.h b/chrome/browser/extensions/extension_function.h
index aed4dda..6e28775 100644
--- a/chrome/browser/extensions/extension_function.h
+++ b/chrome/browser/extensions/extension_function.h
@@ -11,15 +11,19 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/extension.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
+class Browser;
+class ExtensionFunction;
class ExtensionFunctionDispatcher;
+class UIThreadExtensionFunction;
class ListValue;
-class Profile;
class QuotaLimitHeuristic;
+class RenderViewHost;
class Value;
#define EXTENSION_FUNCTION_VALIDATE(test) do { \
@@ -38,56 +42,59 @@ class Value;
#define DECLARE_EXTENSION_FUNCTION_NAME(name) \
public: static const char* function_name() { return name; }
+// Traits that describe how ExtensionFunction should be deleted. This just calls
+// the virtual "Destruct" method on ExtensionFunction, allowing derived classes
+// to override the behavior.
+struct ExtensionFunctionDeleteTraits {
+ public:
+ static void Destruct(const ExtensionFunction* x);
+};
+
// Abstract base class for extension functions the ExtensionFunctionDispatcher
// knows how to dispatch to.
class ExtensionFunction
: public base::RefCountedThreadSafe<ExtensionFunction,
- BrowserThread::DeleteOnUIThread> {
+ ExtensionFunctionDeleteTraits> {
public:
ExtensionFunction();
- virtual ~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;
+ virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() {
+ return NULL;
}
- std::string extension_id() const { return extension_id_; }
- void SetRenderViewHost(RenderViewHost* render_view_host);
- RenderViewHost* render_view_host() const { return render_view_host_; }
+ // Execute the API. Clients should initialize the ExtensionFunction using
+ // SetArgs(), set_request_id(), and the other setters before calling this
+ // method. Derived classes should be ready to return GetResult() and
+ // GetError() before returning from this function.
+ // Note that once Run() returns, dispatcher() can be NULL, so be sure to
+ // NULL-check.
+ virtual void Run();
+
+ // Returns a quota limit heuristic suitable for this function.
+ // No quota limiting by default.
+ virtual void GetQuotaLimitHeuristics(
+ std::list<QuotaLimitHeuristic*>* heuristics) const {}
// Specifies the raw arguments to the function, as a JSON value.
- virtual void SetArgs(const ListValue* args) = 0;
+ virtual void SetArgs(const ListValue* args);
// Retrieves the results of the function as a JSON-encoded string (may
// be empty).
- virtual const std::string GetResult() = 0;
+ virtual const std::string GetResult();
// Retrieves any error string from the function.
- virtual const std::string GetError() = 0;
+ virtual const std::string GetError();
- // Returns a quota limit heuristic suitable for this function.
- // No quota limiting by default.
- virtual void GetQuotaLimitHeuristics(
- std::list<QuotaLimitHeuristic*>* heuristics) const {}
+ // Specifies the name of the function.
+ void set_name(const std::string& name) { name_ = name; }
+ const std::string& name() const { return name_; }
- void set_dispatcher(
- const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher) {
- dispatcher_ = dispatcher;
- }
- ExtensionFunctionDispatcher* dispatcher() const {
- return dispatcher_.get();
- }
+ void set_profile_id(ProfileId profile_id) { profile_id_ = profile_id; }
+ ProfileId profile_id() const { return profile_id_; }
+
+ void set_extension(const Extension* extension) { extension_ = extension; }
+ const Extension* GetExtension() const { return extension_.get(); }
+ const std::string& extension_id() const { return extension_->id(); }
void set_request_id(int request_id) { request_id_ = request_id; }
int request_id() { return request_id_; }
@@ -104,19 +111,110 @@ class ExtensionFunction
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 struct ExtensionFunctionDeleteTraits;
+
+ virtual ~ExtensionFunction();
+
+ // Helper method for ExtensionFunctionDeleteTraits. Deletes this object.
+ virtual void Destruct() const = 0;
+
+ // Derived classes should implement this method to do their work and return
+ // success/failure.
+ virtual bool RunImpl() = 0;
+
+ // Sends the result back to the extension.
+ virtual void SendResponse(bool success) = 0;
+
+ // Called when we receive an extension api request that is invalid in a way
+ // that JSON validation in the renderer should have caught. This should never
+ // happen and could be an attacker trying to exploit the browser, so we crash
+ // the renderer instead.
+ virtual void HandleBadMessage() = 0;
+
+ // Return true if the argument to this function at |index| was provided and
+ // is non-null.
+ bool HasOptionalArgument(size_t index);
+
+ // Id of this request, used to map the response back to the caller.
+ int request_id_;
+
+ // The ID of the Profile of this function's extension.
+ ProfileId profile_id_;
+
+ // The extension that called this function.
+ scoped_refptr<const Extension> extension_;
+
+ // 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_;
+
+ // 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(ExtensionFunction);
+};
+
+// Extension functions that run on the UI thread. Most functions fall into
+// this category.
+class UIThreadExtensionFunction : public ExtensionFunction {
+ public:
+ UIThreadExtensionFunction();
+
+ virtual UIThreadExtensionFunction* AsUIThreadExtensionFunction() OVERRIDE {
+ return this;
+ }
+
+ // 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_; }
+
+ void SetRenderViewHost(RenderViewHost* render_view_host);
+ RenderViewHost* render_view_host() const { return render_view_host_; }
+
+ void set_dispatcher(
+ const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher) {
+ dispatcher_ = dispatcher;
+ }
+ ExtensionFunctionDispatcher* dispatcher() const {
+ return dispatcher_.get();
+ }
protected:
- friend class base::RefCountedThreadSafe<ExtensionFunction>;
+ template<BrowserThread::ID id> friend struct BrowserThread::DeleteOnThread;
+ friend class DeleteTask<UIThreadExtensionFunction>;
+
+ virtual ~UIThreadExtensionFunction();
- // 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();
+ virtual void SendResponse(bool success);
// Gets the "current" browser, if any.
//
@@ -142,34 +240,9 @@ class ExtensionFunction
// The RenderViewHost we will send responses too.
RenderViewHost* render_view_host_;
- // 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_;
-
private:
// Helper class to track the lifetime of ExtensionFunction's RenderViewHost
// pointer and NULL it out when it dies. We use this separate class (instead
@@ -179,71 +252,31 @@ class ExtensionFunction
// method.
class RenderViewHostTracker : public NotificationObserver {
public:
- explicit RenderViewHostTracker(ExtensionFunction* extension_function);
+ explicit RenderViewHostTracker(UIThreadExtensionFunction* function);
private:
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
- ExtensionFunction* function_;
+ UIThreadExtensionFunction* function_;
NotificationRegistrar registrar_;
};
+ virtual void HandleBadMessage();
+
+ virtual void Destruct() const;
+
scoped_ptr<RenderViewHostTracker> tracker_;
- 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 {
+class AsyncExtensionFunction : public UIThreadExtensionFunction {
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_;
-
- private:
- // Called when we receive an extension api request that is invalid in a way
- // that JSON validation in the renderer should have caught. This should never
- // happen and could be an attacker trying to exploit the browser, so we crash
- // the renderer instead.
- void HandleBadMessage();
-
- DISALLOW_COPY_AND_ASSIGN(AsyncExtensionFunction);
};
// A SyncExtensionFunction is an ExtensionFunction that runs synchronously
@@ -253,15 +286,11 @@ class AsyncExtensionFunction : public ExtensionFunction {
//
// 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 {
+class SyncExtensionFunction : public UIThreadExtensionFunction {
public:
SyncExtensionFunction();
- // Derived classes should implement this method to do their work and return
- // success/failure.
- virtual bool RunImpl() = 0;
-
- virtual void Run();
+ virtual void Run() OVERRIDE;
protected:
virtual ~SyncExtensionFunction();
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 2329ae7..a19b839 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -479,10 +479,18 @@ void ExtensionFunctionDispatcher::Dispatch(
scoped_refptr<ExtensionFunction> function(
FactoryRegistry::GetInstance()->NewFunction(params.name));
- function->SetRenderViewHost(render_view_host);
- function->set_dispatcher(AsWeakPtr());
- function->set_profile(profile_);
- function->set_extension_id(extension->id());
+ UIThreadExtensionFunction* function_ui =
+ function->AsUIThreadExtensionFunction();
+ if (!function_ui) {
+ NOTREACHED();
+ return;
+ }
+ function_ui->SetRenderViewHost(render_view_host);
+ function_ui->set_dispatcher(AsWeakPtr());
+ function_ui->set_profile(profile_);
+
+ function->set_profile_id(profile_->GetRuntimeId());
+ function->set_extension(extension);
function->SetArgs(&params.arguments);
function->set_source_url(params.source_url);
function->set_request_id(params.request_id);
diff --git a/chrome/browser/extensions/extension_test_api.cc b/chrome/browser/extensions/extension_test_api.cc
index 2309feb..e5bc60f 100644
--- a/chrome/browser/extensions/extension_test_api.cc
+++ b/chrome/browser/extensions/extension_test_api.cc
@@ -8,6 +8,7 @@
#include "base/memory/singleton.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc
index a38d867..4cbdb93 100644
--- a/chrome/browser/extensions/extension_webstore_private_api.cc
+++ b/chrome/browser/extensions/extension_webstore_private_api.cc
@@ -12,6 +12,7 @@
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/crx_installer.h"
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_install_dialog.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/extensions/extensions_quota_service_unittest.cc b/chrome/browser/extensions/extensions_quota_service_unittest.cc
index 63eedb1..39cd64e3 100644
--- a/chrome/browser/extensions/extensions_quota_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_quota_service_unittest.cc
@@ -56,6 +56,10 @@ class MockFunction : public ExtensionFunction {
virtual const std::string GetError() { return std::string(); }
virtual const std::string GetResult() { return std::string(); }
virtual void Run() {}
+ virtual void Destruct() const { delete this; }
+ virtual bool RunImpl() { return true; }
+ virtual void SendResponse(bool) { }
+ virtual void HandleBadMessage() { }
};
class TimedLimitMockFunction : public MockFunction {