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.
5 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
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"
20 using content::BrowserContext
;
22 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
23 extensions::ChromeExtensionWebContentsObserver
);
25 namespace extensions
{
27 ChromeExtensionWebContentsObserver::ChromeExtensionWebContentsObserver(
28 content::WebContents
* web_contents
)
29 : ExtensionWebContentsObserver(web_contents
) {}
31 ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {}
33 void ChromeExtensionWebContentsObserver::RenderViewCreated(
34 content::RenderViewHost
* render_view_host
) {
35 ReloadIfTerminated(render_view_host
);
36 ExtensionWebContentsObserver::RenderViewCreated(render_view_host
);
39 bool ChromeExtensionWebContentsObserver::OnMessageReceived(
40 const IPC::Message
& message
) {
42 IPC_BEGIN_MESSAGE_MAP(ChromeExtensionWebContentsObserver
, message
)
43 IPC_MESSAGE_HANDLER(ExtensionHostMsg_PostMessage
, OnPostMessage
)
44 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DetailedConsoleMessageAdded
,
45 OnDetailedConsoleMessageAdded
)
46 IPC_MESSAGE_UNHANDLED(handled
= false)
51 void ChromeExtensionWebContentsObserver::OnDetailedConsoleMessageAdded(
52 const base::string16
& message
,
53 const base::string16
& source
,
54 const StackTrace
& stack_trace
,
55 int32 severity_level
) {
56 if (!IsSourceFromAnExtension(source
))
59 content::RenderViewHost
* render_view_host
=
60 web_contents()->GetRenderViewHost();
61 std::string extension_id
= GetExtensionId(render_view_host
);
62 if (extension_id
.empty())
63 extension_id
= GURL(source
).host();
65 ExtensionSystem::Get(browser_context())->error_console()->ReportError(
66 scoped_ptr
<ExtensionError
>(
67 new RuntimeError(extension_id
,
68 browser_context()->IsOffTheRecord(),
72 web_contents()->GetLastCommittedURL(),
73 static_cast<logging::LogSeverity
>(severity_level
),
74 render_view_host
->GetRoutingID(),
75 render_view_host
->GetProcess()->GetID())));
78 void ChromeExtensionWebContentsObserver::OnPostMessage(int port_id
,
79 const Message
& message
) {
80 MessageService
* message_service
= MessageService::Get(browser_context());
81 if (message_service
) {
82 message_service
->PostMessage(port_id
, message
);
86 void ChromeExtensionWebContentsObserver::ReloadIfTerminated(
87 content::RenderViewHost
* render_view_host
) {
88 std::string extension_id
= GetExtensionId(render_view_host
);
89 if (extension_id
.empty())
92 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
94 // Reload the extension if it has crashed.
95 // TODO(yoz): This reload doesn't happen synchronously for unpacked
96 // extensions. It seems to be fast enough, but there is a race.
97 // We should delay loading until the extension has reloaded.
98 if (registry
->GetExtensionById(extension_id
, ExtensionRegistry::TERMINATED
)) {
99 ExtensionSystem::Get(browser_context())->
100 extension_service()->ReloadExtension(extension_id
);
104 } // namespace extensions