1 // Copyright 2013 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/renderer/extensions/console.h"
7 #include "base/compiler_specific.h"
8 #include "base/debug/alias.h"
9 #include "base/lazy_instance.h"
10 #include "base/string_util.h"
11 #include "base/stringprintf.h"
12 #include "base/utf_string_conversions.h"
13 #include "chrome/renderer/extensions/dispatcher.h"
14 #include "chrome/renderer/extensions/extension_helper.h"
15 #include "content/public/renderer/render_view.h"
16 #include "content/public/renderer/render_view_visitor.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
21 namespace extensions
{
26 // Finds the RenderView associated with a context. Note: there will be multiple
27 // contexts in each RenderView.
28 class ByContextFinder
: public content::RenderViewVisitor
{
30 static content::RenderView
* Find(v8::Handle
<v8::Context
> context
) {
31 ByContextFinder
finder(context
);
32 content::RenderView::ForEach(&finder
);
37 explicit ByContextFinder(v8::Handle
<v8::Context
> context
)
38 : context_(context
), found_(NULL
) {
41 virtual bool Visit(content::RenderView
* render_view
) OVERRIDE
{
42 ExtensionHelper
* helper
= ExtensionHelper::Get(render_view
);
44 helper
->dispatcher()->v8_context_set().GetByV8Context(context_
)) {
50 v8::Handle
<v8::Context
> context_
;
51 content::RenderView
* found_
;
53 DISALLOW_COPY_AND_ASSIGN(ByContextFinder
);
56 // Writes |message| to stack to show up in minidump, then crashes.
57 void CheckWithMinidump(const std::string
& message
) {
59 base::debug::Alias(&minidump
);
60 base::snprintf(minidump
, arraysize(minidump
),
61 "e::console: %s", message
.c_str());
62 CHECK(false) << message
;
67 void Debug(content::RenderView
* render_view
, const std::string
& message
) {
68 AddMessage(render_view
, content::CONSOLE_MESSAGE_LEVEL_DEBUG
, message
);
71 void Log(content::RenderView
* render_view
, const std::string
& message
) {
72 AddMessage(render_view
, content::CONSOLE_MESSAGE_LEVEL_LOG
, message
);
75 void Warn(content::RenderView
* render_view
, const std::string
& message
) {
76 AddMessage(render_view
, content::CONSOLE_MESSAGE_LEVEL_WARNING
, message
);
79 void Error(content::RenderView
* render_view
, const std::string
& message
) {
80 AddMessage(render_view
, content::CONSOLE_MESSAGE_LEVEL_ERROR
, message
);
83 void Fatal(content::RenderView
* render_view
, const std::string
& message
) {
84 Error(render_view
, message
);
85 CheckWithMinidump(message
);
88 void AddMessage(content::RenderView
* render_view
,
89 content::ConsoleMessageLevel level
,
90 const std::string
& message
) {
91 WebKit::WebView
* web_view
= render_view
->GetWebView();
92 if (!web_view
|| !web_view
->mainFrame())
94 WebKit::WebConsoleMessage::Level target_level
=
95 WebKit::WebConsoleMessage::LevelLog
;
97 case content::CONSOLE_MESSAGE_LEVEL_DEBUG
:
98 target_level
= WebKit::WebConsoleMessage::LevelDebug
;
100 case content::CONSOLE_MESSAGE_LEVEL_LOG
:
101 target_level
= WebKit::WebConsoleMessage::LevelLog
;
103 case content::CONSOLE_MESSAGE_LEVEL_WARNING
:
104 target_level
= WebKit::WebConsoleMessage::LevelWarning
;
106 case content::CONSOLE_MESSAGE_LEVEL_ERROR
:
107 target_level
= WebKit::WebConsoleMessage::LevelError
;
110 web_view
->mainFrame()->addMessageToConsole(
111 WebKit::WebConsoleMessage(target_level
, ASCIIToUTF16(message
)));
114 void Debug(v8::Handle
<v8::Context
> context
, const std::string
& message
) {
115 AddMessage(context
, content::CONSOLE_MESSAGE_LEVEL_DEBUG
, message
);
118 void Log(v8::Handle
<v8::Context
> context
, const std::string
& message
) {
119 AddMessage(context
, content::CONSOLE_MESSAGE_LEVEL_LOG
, message
);
122 void Warn(v8::Handle
<v8::Context
> context
, const std::string
& message
) {
123 AddMessage(context
, content::CONSOLE_MESSAGE_LEVEL_WARNING
, message
);
126 void Error(v8::Handle
<v8::Context
> context
, const std::string
& message
) {
127 AddMessage(context
, content::CONSOLE_MESSAGE_LEVEL_ERROR
, message
);
130 void Fatal(v8::Handle
<v8::Context
> context
, const std::string
& message
) {
131 Error(context
, message
);
132 CheckWithMinidump(message
);
135 void AddMessage(v8::Handle
<v8::Context
> context
,
136 content::ConsoleMessageLevel level
,
137 const std::string
& message
) {
138 if (context
.IsEmpty()) {
139 LOG(WARNING
) << "Could not log \"" << message
<< "\": no context given";
142 content::RenderView
* render_view
= ByContextFinder::Find(context
);
144 LOG(WARNING
) << "Could not log \"" << message
<< "\": no render view found";
147 AddMessage(render_view
, level
, message
);
150 } // namespace console
151 } // namespace extensions