1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" 6 7#include "chrome/browser/extensions/error_console/error_console.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/common/extensions/chrome_extension_messages.h" 10#include "content/public/browser/browser_context.h" 11#include "content/public/browser/render_process_host.h" 12#include "content/public/browser/render_view_host.h" 13#include "extensions/browser/extension_registry.h" 14#include "extensions/browser/extension_system.h" 15#include "extensions/common/extension_messages.h" 16#include "extensions/common/extension_urls.h" 17 18using content::BrowserContext; 19 20DEFINE_WEB_CONTENTS_USER_DATA_KEY( 21 extensions::ChromeExtensionWebContentsObserver); 22 23namespace extensions { 24 25ChromeExtensionWebContentsObserver::ChromeExtensionWebContentsObserver( 26 content::WebContents* web_contents) 27 : ExtensionWebContentsObserver(web_contents) {} 28 29ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {} 30 31void ChromeExtensionWebContentsObserver::RenderViewCreated( 32 content::RenderViewHost* render_view_host) { 33 ReloadIfTerminated(render_view_host); 34 ExtensionWebContentsObserver::RenderViewCreated(render_view_host); 35} 36 37bool ChromeExtensionWebContentsObserver::OnMessageReceived( 38 const IPC::Message& message, 39 content::RenderFrameHost* render_frame_host) { 40 bool handled = true; 41 IPC_BEGIN_MESSAGE_MAP(ChromeExtensionWebContentsObserver, message) 42 IPC_MESSAGE_HANDLER(ExtensionHostMsg_DetailedConsoleMessageAdded, 43 OnDetailedConsoleMessageAdded) 44 IPC_MESSAGE_UNHANDLED(handled = false) 45 IPC_END_MESSAGE_MAP() 46 return handled; 47} 48 49void ChromeExtensionWebContentsObserver::OnDetailedConsoleMessageAdded( 50 const base::string16& message, 51 const base::string16& source, 52 const StackTrace& stack_trace, 53 int32 severity_level) { 54 if (!IsSourceFromAnExtension(source)) 55 return; 56 57 content::RenderViewHost* render_view_host = 58 web_contents()->GetRenderViewHost(); 59 std::string extension_id = GetExtensionId(render_view_host); 60 if (extension_id.empty()) 61 extension_id = GURL(source).host(); 62 63 ExtensionSystem::Get(browser_context())->error_console()->ReportError( 64 scoped_ptr<ExtensionError>( 65 new RuntimeError(extension_id, 66 browser_context()->IsOffTheRecord(), 67 source, 68 message, 69 stack_trace, 70 web_contents()->GetLastCommittedURL(), 71 static_cast<logging::LogSeverity>(severity_level), 72 render_view_host->GetRoutingID(), 73 render_view_host->GetProcess()->GetID()))); 74} 75 76void ChromeExtensionWebContentsObserver::ReloadIfTerminated( 77 content::RenderViewHost* render_view_host) { 78 std::string extension_id = GetExtensionId(render_view_host); 79 if (extension_id.empty()) 80 return; 81 82 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); 83 84 // Reload the extension if it has crashed. 85 // TODO(yoz): This reload doesn't happen synchronously for unpacked 86 // extensions. It seems to be fast enough, but there is a race. 87 // We should delay loading until the extension has reloaded. 88 if (registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED)) { 89 ExtensionSystem::Get(browser_context())-> 90 extension_service()->ReloadExtension(extension_id); 91 } 92} 93 94} // namespace extensions 95