extensions_render_frame_observer.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. #include "extensions/renderer/extensions_render_frame_observer.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/bind.h"
  10. #include "base/strings/string_split.h"
  11. #include "base/strings/utf_string_conversions.h"
  12. #include "content/public/renderer/render_frame.h"
  13. #include "extensions/common/extension_messages.h"
  14. #include "extensions/common/logging_constants.h"
  15. #include "extensions/common/stack_frame.h"
  16. #include "third_party/blink/public/web/web_frame_widget.h"
  17. #include "third_party/blink/public/web/web_local_frame.h"
  18. namespace extensions {
  19. namespace {
  20. // The delimiter for a stack trace provided by WebKit.
  21. const char16_t kStackFrameDelimiter[] = u"\n at ";
  22. // Get a stack trace from a WebKit console message.
  23. // There are three possible scenarios:
  24. // 1. WebKit gives us a stack trace in |stack_trace|.
  25. // 2. The stack trace is embedded in the error |message| by an internal
  26. // script. This will be more useful than |stack_trace|, since |stack_trace|
  27. // will include the internal bindings trace, instead of a developer's code.
  28. // 3. No stack trace is included. In this case, we should mock one up from
  29. // the given line number and source.
  30. // |message| will be populated with the error message only (i.e., will not
  31. // include any stack trace).
  32. StackTrace GetStackTraceFromMessage(std::u16string* message,
  33. const std::u16string& source,
  34. const std::u16string& stack_trace,
  35. int32_t line_number) {
  36. StackTrace result;
  37. std::vector<std::u16string> pieces;
  38. size_t index = 0;
  39. if (message->find(kStackFrameDelimiter) != std::u16string::npos) {
  40. pieces = base::SplitStringUsingSubstr(*message, kStackFrameDelimiter,
  41. base::TRIM_WHITESPACE,
  42. base::SPLIT_WANT_ALL);
  43. *message = pieces[0];
  44. index = 1;
  45. } else if (!stack_trace.empty()) {
  46. pieces = base::SplitStringUsingSubstr(stack_trace, kStackFrameDelimiter,
  47. base::TRIM_WHITESPACE,
  48. base::SPLIT_WANT_ALL);
  49. }
  50. // If we got a stack trace, parse each frame from the text.
  51. if (index < pieces.size()) {
  52. for (; index < pieces.size(); ++index) {
  53. std::unique_ptr<StackFrame> frame =
  54. StackFrame::CreateFromText(pieces[index]);
  55. if (frame.get())
  56. result.push_back(*frame);
  57. }
  58. }
  59. if (result.empty()) { // If we don't have a stack trace, mock one up.
  60. result.push_back(StackFrame(line_number,
  61. 1u, // column number
  62. source,
  63. std::u16string() /* no function name */));
  64. }
  65. return result;
  66. }
  67. } // namespace
  68. ExtensionsRenderFrameObserver::ExtensionsRenderFrameObserver(
  69. content::RenderFrame* render_frame,
  70. service_manager::BinderRegistry* registry)
  71. : content::RenderFrameObserver(render_frame) {
  72. registry->AddInterface(
  73. base::BindRepeating(&ExtensionsRenderFrameObserver::BindAppWindowReceiver,
  74. base::Unretained(this)));
  75. }
  76. ExtensionsRenderFrameObserver::~ExtensionsRenderFrameObserver() {
  77. }
  78. void ExtensionsRenderFrameObserver::BindAppWindowReceiver(
  79. mojo::PendingReceiver<mojom::AppWindow> receiver) {
  80. receivers_.Add(this, std::move(receiver));
  81. }
  82. void ExtensionsRenderFrameObserver::SetVisuallyDeemphasized(bool deemphasized) {
  83. // TODO(danakj): This mojo API should be a MainFrame-only interface and object
  84. // rather than an every-frame interface and object.
  85. DCHECK(render_frame()->IsMainFrame());
  86. if (webview_visually_deemphasized_ == deemphasized)
  87. return;
  88. webview_visually_deemphasized_ = deemphasized;
  89. SkColor color =
  90. deemphasized ? SkColorSetARGB(178, 0, 0, 0) : SK_ColorTRANSPARENT;
  91. render_frame()->GetWebFrame()->FrameWidget()->SetMainFrameOverlayColor(color);
  92. }
  93. void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
  94. const std::u16string& message,
  95. const std::u16string& source,
  96. const std::u16string& stack_trace_string,
  97. uint32_t line_number,
  98. int32_t severity_level) {
  99. if (severity_level <
  100. static_cast<int32_t>(extension_misc::kMinimumSeverityToReportError)) {
  101. // We don't report certain low-severity errors.
  102. return;
  103. }
  104. std::u16string trimmed_message = message;
  105. StackTrace stack_trace = GetStackTraceFromMessage(
  106. &trimmed_message,
  107. source,
  108. stack_trace_string,
  109. line_number);
  110. Send(new ExtensionHostMsg_DetailedConsoleMessageAdded(
  111. routing_id(), trimmed_message, source, stack_trace, severity_level));
  112. }
  113. void ExtensionsRenderFrameObserver::OnDestruct() {
  114. delete this;
  115. }
  116. } // namespace extensions