diff options
Diffstat (limited to 'chrome/browser/extensions/extension_function.cc')
-rw-r--r-- | chrome/browser/extensions/extension_function.cc | 56 |
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); } } |