123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file. 423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" 623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/extensions/error_console/error_console.h" 823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/chrome_extension_messages.h" 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/public/browser/browser_context.h" 1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/public/browser/render_process_host.h" 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_registry.h" 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_system.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/common/extension_messages.h" 1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/common/extension_urls.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)using content::BrowserContext; 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY( 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) extensions::ChromeExtensionWebContentsObserver); 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace extensions { 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ChromeExtensionWebContentsObserver::ChromeExtensionWebContentsObserver( 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) content::WebContents* web_contents) 2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) : ExtensionWebContentsObserver(web_contents) {} 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {} 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ChromeExtensionWebContentsObserver::RenderViewCreated( 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) content::RenderViewHost* render_view_host) { 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ReloadIfTerminated(render_view_host); 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ExtensionWebContentsObserver::RenderViewCreated(render_view_host); 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool ChromeExtensionWebContentsObserver::OnMessageReceived( 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const IPC::Message& message, 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::RenderFrameHost* render_frame_host) { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool handled = true; 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ChromeExtensionWebContentsObserver, message) 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IPC_MESSAGE_HANDLER(ExtensionHostMsg_DetailedConsoleMessageAdded, 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) OnDetailedConsoleMessageAdded) 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) IPC_END_MESSAGE_MAP() 4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return handled; 4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ChromeExtensionWebContentsObserver::OnDetailedConsoleMessageAdded( 5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const base::string16& message, 5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const base::string16& source, 5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const StackTrace& stack_trace, 5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int32 severity_level) { 5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!IsSourceFromAnExtension(source)) 5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) content::RenderViewHost* render_view_host = 5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) web_contents()->GetRenderViewHost(); 5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string extension_id = GetExtensionId(render_view_host); 6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (extension_id.empty()) 6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) extension_id = GURL(source).host(); 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ExtensionSystem::Get(browser_context())->error_console()->ReportError( 6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<ExtensionError>( 6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new RuntimeError(extension_id, 6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) browser_context()->IsOffTheRecord(), 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) source, 6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) message, 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) stack_trace, 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) web_contents()->GetLastCommittedURL(), 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) static_cast<logging::LogSeverity>(severity_level), 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) render_view_host->GetRoutingID(), 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) render_view_host->GetProcess()->GetID()))); 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ChromeExtensionWebContentsObserver::ReloadIfTerminated( 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) content::RenderViewHost* render_view_host) { 7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string extension_id = GetExtensionId(render_view_host); 7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (extension_id.empty()) 8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Reload the extension if it has crashed. 8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(yoz): This reload doesn't happen synchronously for unpacked 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // extensions. It seems to be fast enough, but there is a race. 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // We should delay loading until the extension has reloaded. 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED)) { 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ExtensionSystem::Get(browser_context())-> 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) extension_service()->ReloadExtension(extension_id); 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace extensions 95