summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_function.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions/extension_function.cc')
-rw-r--r--chrome/browser/extensions/extension_function.cc56
1 files changed, 51 insertions, 5 deletions
diff --git a/chrome/browser/extensions/extension_function.cc b/chrome/browser/extensions/extension_function.cc
index 9f0d065..f390d72 100644
--- a/chrome/browser/extensions/extension_function.cc
+++ b/chrome/browser/extensions/extension_function.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// 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.
@@ -9,6 +9,31 @@
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/extension_messages.h"
+#include "content/browser/renderer_host/render_process_host.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/user_metrics.h"
+#include "content/common/notification_source.h"
+#include "content/common/notification_type.h"
+#include "content/common/result_codes.h"
+
+ExtensionFunction::RenderViewHostTracker::RenderViewHostTracker(
+ ExtensionFunction* function)
+ : function_(function) {
+ registrar_.Add(this,
+ NotificationType::RENDER_VIEW_HOST_DELETED,
+ Source<RenderViewHost>(function->render_view_host()));
+}
+
+void ExtensionFunction::RenderViewHostTracker::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ CHECK(type == NotificationType::RENDER_VIEW_HOST_DELETED);
+ CHECK(Source<RenderViewHost>(source).ptr() ==
+ function_->render_view_host());
+ function_->SetRenderViewHost(NULL);
+}
ExtensionFunction::ExtensionFunction()
: request_id_(-1),
@@ -21,6 +46,11 @@ ExtensionFunction::ExtensionFunction()
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);
@@ -28,7 +58,7 @@ const Extension* ExtensionFunction::GetExtension() {
}
Browser* ExtensionFunction::GetCurrentBrowser() {
- return dispatcher()->GetCurrentBrowser(include_incognito_);
+ return dispatcher()->GetCurrentBrowser(render_view_host_, include_incognito_);
}
AsyncExtensionFunction::AsyncExtensionFunction()
@@ -61,12 +91,28 @@ void AsyncExtensionFunction::Run() {
}
void AsyncExtensionFunction::SendResponse(bool success) {
- if (!dispatcher())
+ if (!render_view_host_ || !dispatcher())
return;
if (bad_message_) {
- dispatcher()->HandleBadMessage(this);
+ HandleBadMessage();
+ return;
+ }
+
+ render_view_host_->Send(new ExtensionMsg_Response(
+ render_view_host_->routing_id(), request_id_, success,
+ GetResult(), GetError()));
+}
+
+void AsyncExtensionFunction::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.
+ CHECK(false);
} else {
- dispatcher()->SendResponse(this, success);
+ NOTREACHED();
+ UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD"));
+ base::KillProcess(render_view_host_->process()->GetHandle(),
+ ResultCodes::KILLED_BAD_MESSAGE, false);
}
}