Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / extensions / renderer / extensions_render_frame_observer.cc
blobf75e27c23bea81d5bfaa7c676444dc98540952a0
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 "extensions/renderer/extensions_render_frame_observer.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/public/renderer/render_frame.h"
10 #include "extensions/common/extension_messages.h"
11 #include "extensions/common/stack_frame.h"
12 #include "third_party/WebKit/public/web/WebLocalFrame.h"
14 namespace extensions {
16 namespace {
18 // The delimiter for a stack trace provided by WebKit.
19 const char kStackFrameDelimiter[] = "\n at ";
21 // Get a stack trace from a WebKit console message.
22 // There are three possible scenarios:
23 // 1. WebKit gives us a stack trace in |stack_trace|.
24 // 2. The stack trace is embedded in the error |message| by an internal
25 // script. This will be more useful than |stack_trace|, since |stack_trace|
26 // will include the internal bindings trace, instead of a developer's code.
27 // 3. No stack trace is included. In this case, we should mock one up from
28 // the given line number and source.
29 // |message| will be populated with the error message only (i.e., will not
30 // include any stack trace).
31 StackTrace GetStackTraceFromMessage(
32 base::string16* message,
33 const base::string16& source,
34 const base::string16& stack_trace,
35 int32 line_number) {
36 StackTrace result;
37 std::vector<base::string16> pieces;
38 size_t index = 0;
40 if (message->find(base::UTF8ToUTF16(kStackFrameDelimiter)) !=
41 base::string16::npos) {
42 base::SplitStringUsingSubstr(*message,
43 base::UTF8ToUTF16(kStackFrameDelimiter),
44 &pieces);
45 *message = pieces[0];
46 index = 1;
47 } else if (!stack_trace.empty()) {
48 base::SplitStringUsingSubstr(stack_trace,
49 base::UTF8ToUTF16(kStackFrameDelimiter),
50 &pieces);
53 // If we got a stack trace, parse each frame from the text.
54 if (index < pieces.size()) {
55 for (; index < pieces.size(); ++index) {
56 scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(pieces[index]);
57 if (frame.get())
58 result.push_back(*frame);
62 if (result.empty()) { // If we don't have a stack trace, mock one up.
63 result.push_back(
64 StackFrame(line_number,
65 1u, // column number
66 source,
67 base::string16() /* no function name */ ));
70 return result;
73 } // namespace
75 ExtensionsRenderFrameObserver::ExtensionsRenderFrameObserver(
76 content::RenderFrame* render_frame)
77 : content::RenderFrameObserver(render_frame) {
80 ExtensionsRenderFrameObserver::~ExtensionsRenderFrameObserver() {
83 void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
84 const base::string16& message,
85 const base::string16& source,
86 const base::string16& stack_trace_string,
87 int32 line_number,
88 int32 severity_level) {
89 base::string16 trimmed_message = message;
90 StackTrace stack_trace = GetStackTraceFromMessage(
91 &trimmed_message,
92 source,
93 stack_trace_string,
94 line_number);
95 Send(new ExtensionHostMsg_DetailedConsoleMessageAdded(
96 routing_id(), trimmed_message, source, stack_trace, severity_level));
99 } // namespace extensions