chrome_extension_web_contents_observer.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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/api/messaging/message_service.h" 8#include "chrome/browser/extensions/error_console/error_console.h" 9#include "chrome/browser/extensions/extension_service.h" 10#include "chrome/common/render_messages.h" 11#include "content/public/browser/browser_context.h" 12#include "content/public/browser/render_process_host.h" 13#include "content/public/browser/render_view_host.h" 14#include "extensions/browser/extension_registry.h" 15#include "extensions/browser/extension_system.h" 16#include "extensions/common/api/messaging/message.h" 17#include "extensions/common/extension_messages.h" 18#include "extensions/common/extension_urls.h" 19 20using content::BrowserContext; 21 22DEFINE_WEB_CONTENTS_USER_DATA_KEY( 23 extensions::ChromeExtensionWebContentsObserver); 24 25namespace extensions { 26 27ChromeExtensionWebContentsObserver::ChromeExtensionWebContentsObserver( 28 content::WebContents* web_contents) 29 : ExtensionWebContentsObserver(web_contents) {} 30 31ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {} 32 33void ChromeExtensionWebContentsObserver::RenderViewCreated( 34 content::RenderViewHost* render_view_host) { 35 ReloadIfTerminated(render_view_host); 36 ExtensionWebContentsObserver::RenderViewCreated(render_view_host); 37} 38 39bool ChromeExtensionWebContentsObserver::OnMessageReceived( 40 const IPC::Message& message) { 41 bool handled = true; 42 IPC_BEGIN_MESSAGE_MAP(ChromeExtensionWebContentsObserver, message) 43 IPC_MESSAGE_HANDLER(ExtensionHostMsg_PostMessage, OnPostMessage) 44 IPC_MESSAGE_UNHANDLED(handled = false) 45 IPC_END_MESSAGE_MAP() 46 return handled; 47} 48 49bool ChromeExtensionWebContentsObserver::OnMessageReceived( 50 const IPC::Message& message, 51 content::RenderFrameHost* render_frame_host) { 52 bool handled = true; 53 IPC_BEGIN_MESSAGE_MAP(ChromeExtensionWebContentsObserver, message) 54 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DetailedConsoleMessageAdded, 55 OnDetailedConsoleMessageAdded) 56 IPC_MESSAGE_UNHANDLED(handled = false) 57 IPC_END_MESSAGE_MAP() 58 return handled; 59} 60 61void ChromeExtensionWebContentsObserver::OnDetailedConsoleMessageAdded( 62 const base::string16& message, 63 const base::string16& source, 64 const StackTrace& stack_trace, 65 int32 severity_level) { 66 if (!IsSourceFromAnExtension(source)) 67 return; 68 69 content::RenderViewHost* render_view_host = 70 web_contents()->GetRenderViewHost(); 71 std::string extension_id = GetExtensionId(render_view_host); 72 if (extension_id.empty()) 73 extension_id = GURL(source).host(); 74 75 ExtensionSystem::Get(browser_context())->error_console()->ReportError( 76 scoped_ptr<ExtensionError>( 77 new RuntimeError(extension_id, 78 browser_context()->IsOffTheRecord(), 79 source, 80 message, 81 stack_trace, 82 web_contents()->GetLastCommittedURL(), 83 static_cast<logging::LogSeverity>(severity_level), 84 render_view_host->GetRoutingID(), 85 render_view_host->GetProcess()->GetID()))); 86} 87 88void ChromeExtensionWebContentsObserver::OnPostMessage(int port_id, 89 const Message& message) { 90 MessageService* message_service = MessageService::Get(browser_context()); 91 if (message_service) { 92 message_service->PostMessage(port_id, message); 93 } 94} 95 96void ChromeExtensionWebContentsObserver::ReloadIfTerminated( 97 content::RenderViewHost* render_view_host) { 98 std::string extension_id = GetExtensionId(render_view_host); 99 if (extension_id.empty()) 100 return; 101 102 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); 103 104 // Reload the extension if it has crashed. 105 // TODO(yoz): This reload doesn't happen synchronously for unpacked 106 // extensions. It seems to be fast enough, but there is a race. 107 // We should delay loading until the extension has reloaded. 108 if (registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED)) { 109 ExtensionSystem::Get(browser_context())-> 110 extension_service()->ReloadExtension(extension_id); 111 } 112} 113 114} // namespace extensions 115