#include "extensions/renderer/extensions_render_frame_observer.h"
#include <stddef.h>
#include <memory>
#include <utility>
#include <vector>
#include "base/functional/bind.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/renderer/render_frame.h"
#include "extensions/common/logging_constants.h"
#include "extensions/common/stack_frame.h"
#include "extensions/renderer/extension_frame_helper.h"
#include "third_party/blink/public/common/logging/logging_utils.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
namespace extensions {
namespace {
const char16_t kStackFrameDelimiter[] = u"\n at ";
StackTrace GetStackTraceFromMessage(std::u16string* message,
const std::u16string& source,
const std::u16string& stack_trace,
int32_t line_number) {
StackTrace result;
std::vector<std::u16string> pieces;
size_t index = 0;
if (message->find(kStackFrameDelimiter) != std::u16string::npos) {
pieces = base::SplitStringUsingSubstr(*message, kStackFrameDelimiter,
base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL);
*message = pieces[0];
index = 1;
} else if (!stack_trace.empty()) {
pieces = base::SplitStringUsingSubstr(stack_trace, kStackFrameDelimiter,
base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL);
}
if (index < pieces.size()) {
for (; index < pieces.size(); ++index) {
std::unique_ptr<StackFrame> frame =
StackFrame::CreateFromText(pieces[index]);
if (frame.get())
result.push_back(*frame);
}
}
if (result.empty()) {
result.push_back(StackFrame(line_number,
1u,
source,
std::u16string() ));
}
return result;
}
}
ExtensionsRenderFrameObserver::ExtensionsRenderFrameObserver(
content::RenderFrame* render_frame,
service_manager::BinderRegistry* registry)
: content::RenderFrameObserver(render_frame) {
registry->AddInterface(
base::BindRepeating(&ExtensionsRenderFrameObserver::BindAppWindowReceiver,
base::Unretained(this)));
}
ExtensionsRenderFrameObserver::~ExtensionsRenderFrameObserver() {
}
void ExtensionsRenderFrameObserver::BindAppWindowReceiver(
mojo::PendingReceiver<mojom::AppWindow> receiver) {
receivers_.Add(this, std::move(receiver));
}
void ExtensionsRenderFrameObserver::SetVisuallyDeemphasized(bool deemphasized) {
DCHECK(render_frame()->IsMainFrame());
if (webview_visually_deemphasized_ == deemphasized)
return;
webview_visually_deemphasized_ = deemphasized;
SkColor color =
deemphasized ? SkColorSetARGB(178, 0, 0, 0) : SK_ColorTRANSPARENT;
render_frame()->GetWebFrame()->FrameWidget()->SetMainFrameOverlayColor(color);
}
void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded(
const std::u16string& message,
const std::u16string& source,
const std::u16string& stack_trace_string,
uint32_t line_number,
blink::mojom::ConsoleMessageLevel level) {
if (blink::ConsoleMessageLevelToLogSeverity(level) <
static_cast<int32_t>(extension_misc::kMinimumSeverityToReportError)) {
return;
}
std::u16string trimmed_message = message;
StackTrace stack_trace = GetStackTraceFromMessage(
&trimmed_message,
source,
stack_trace_string,
line_number);
ExtensionFrameHelper::Get(render_frame())
->GetLocalFrameHost()
->DetailedConsoleMessageAdded(trimmed_message, source, stack_trace,
level);
}
void ExtensionsRenderFrameObserver::OnDestruct() {
delete this;
}
}